Skip to main content
The Keloa Zapier integration connects a Keloa workspace to thousands of apps. Zaps start on Keloa events (a new conversation, a customer message, a Zap command a teammate runs from the inbox) and can create contacts and conversations, reply, add notes and tags, and update conversations. This page has two parts:
  • Connect Zapier — for teams who want to use Keloa in their Zaps.
  • API reference — the OAuth 2 flow, the endpoints, the REST hooks and the payloads the integration uses.
The API on this page exists for the Keloa Zapier integration. Only Zapier can get an access token for it: the OAuth client is Zapier, and Keloa only redirects to Zapier’s own OAuth return address. To call Keloa from your own code, use Webhooks and the Custom HTTP tool.

Connect Zapier

Who can connect

  • Role. Only workspace owners and admins can connect Keloa to Zapier. See Members & roles.
  • Plan. Zapier works on every plan. It uses one integration slot per workspace, however many teammates connect it: Starter includes 1 slot, Growth 5, Business 15 and Scale unlimited. See Plans.
  • Per-plan actions. Add Internal Note needs Growth or higher, because internal notes do. Keloa only sends email from a workspace with a verified email domain, which needs Growth or higher. Without one, Create Conversation and replies on email conversations are kept in the conversation but not sent.

Set it up

1

Open Keloa on Zapier

In Keloa, open Integrations in the sidebar, select the Zapier tile and click Open Keloa on Zapier. Or search for Keloa when you add a step to a Zap.
2

Pick a Keloa trigger or action

Create a Zap and pick one of the Keloa triggers, actions or searches. Zapier asks you to sign in to Keloa.
3

Allow access to your workspace

Sign in to Keloa. The consent page shows the workspace you have open and what Zapier may do there. Click Allow access to your workspace. If you’re an owner or admin of other workspaces, the page offers to connect one of those instead.
4

Build your Zap

Zapier labels the connection with the workspace name and your email address. Zaps act as you: replies and notes show your name, and the conversations you reply to are assigned to you, as if you had done it in the inbox.

What you can do in a Zap

Triggers

All triggers are instant (REST hooks). See Events for the data each one sends.

Actions

Searches

Zap commands

A Zap command lets a teammate start a Zap from a conversation. Turn on a Zap with the New Zap Command trigger and give it a command name, for example refund. Then, in a conversation:
  • Type /zap in the composer and pick a command, or
  • click the Zapier button next to the composer (Run a Zap).
You can add optional details for the Zap, for example 12.50 damaged. Keloa sends the conversation, its contact, the teammate, the command and the details to every Zap that listens for that command. The command never reaches the contact. Keloa adds an internal note to the conversation that says who ran which command.
  • A command name uses lowercase letters, digits, dashes and underscores, starts with a letter or digit and is at most 48 characters long. A leading / is dropped and uppercase is lowered.
  • A Zap with the trigger’s Command filter left empty listens for every command. Then teammates can type any command name.
  • Every teammate except viewers can run Zap commands.
  • If no Zap listens for a command, Keloa refuses to run it.

See and remove connections

Open Integrations → Zapier in Keloa. It lists each teammate who connected Zapier, when they connected, when the connection was last used, how many live Zaps it has, and the Zap commands Zaps listen for. Owners and admins can Disconnect a connection: its Zaps stop receiving Keloa events and can no longer act in the workspace. When the last connection is gone, Zapier frees its integration slot. A connection also ends on its own when the teammate who made it leaves the workspace. When they’re no longer an owner or admin, the connection stops working: API calls are refused right away, and the connection ends when Zapier next refreshes its access token or delivers an event.

API reference

Basics

Every API call runs as the teammate who connected, in the workspace they approved, whatever workspace that teammate has open in the app. Records of other workspaces don’t exist for the call: their IDs answer 404, and searches never return them. Optional fields that are missing, null or an empty string are ignored: an update only changes the fields you send with a value.

OAuth 2.0

Keloa is an OAuth 2.0 authorization server (RFC 6749) with PKCE (RFC 7636) and token revocation (RFC 7009).

1. Authorize

Zapier sends the teammate’s browser to the consent page:
The teammate signs in to Keloa if needed, then sees the consent page for the workspace they have open. When they approve, Keloa redirects to the redirect_uri:
Errors:

2. Exchange the code for tokens

200 OK
Token responses carry Cache-Control: no-store. A code is valid once. If a used code is presented again, Keloa refuses it and also revokes the connection that code created, because someone else may hold it.

3. Refresh the access token

When an API call answers 401, refresh the access token:
200 OK
A refresh returns a new access token and the same refresh token. The previous access token stops working at once. If the teammate who connected is no longer an owner or admin of the workspace, the refresh fails with invalid_grant and Keloa revokes the connection: reconnect with an owner or admin account.

4. Revoke a token

200 OK
token can be the access token or the refresh token: either one ends the whole connection. Its tokens stop working, its REST hooks are deleted, and when it was the workspace’s last Zapier connection, the integration slot is freed. An unknown or already revoked token also answers 200.

Token endpoint errors

Errors from /oauth/token and /oauth/revoke use the OAuth 2.0 error format:
400 Bad Request

Authentication

Send the access token as a bearer token on every API call:

Rate limits

Over the limit, Keloa answers 429 with a Retry-After header (seconds) and {"message": "Too Many Attempts."}. API responses also carry X-RateLimit-Limit and X-RateLimit-Remaining.

Errors

The API always answers JSON, whatever Accept header you send. Every error body has a message. Validation errors (422) also list the fields:
422 Unprocessable Content

Objects

Every endpoint and every event uses the same object shapes, so a field you map in a Zap is the same in test and live runs.

Conversation

Contact

Teammate

Message

Used by the message.received event:

Endpoints

All paths are relative to https://app.keloa.ai/api/zapier/v1.

GET /me

Who connected, and to which workspace. Zapier uses it to test the connection and labels the connection <workspace_name> (<email>).
200 OK
id is the connection’s ID.

GET /users

The workspace’s teammates who can take conversations (owners, admins and agents; viewers are left out), sorted by name.
200 OK

GET /teams

The workspace’s teams, sorted by name.
200 OK

POST /hooks

Subscribes a REST hook: Keloa POSTs each matching event to target_url until the hook is deleted. Zapier calls this when a Zap with a Keloa trigger is turned on. A filter that doesn’t belong to the event is ignored. An empty filter matches everything.
201 Created
Errors (422): a target_url that isn’t a Zapier hook URL, an unknown event, an invalid command, or a workspace that already has 500 live hooks.

DELETE /hooks/{id}

Unsubscribes a REST hook. Zapier calls this when the Zap is turned off or deleted. It’s idempotent: a hook that’s already gone (or belongs to another workspace) answers the same, and nothing is deleted outside the connected workspace.
200 OK

GET /triggers/{event}/samples

Up to 3 recent real events of the workspace, newest first, in exactly the payload shape of the event. Zapier uses them to test a trigger and to show sample data in the Zap editor. An empty workspace returns []. Samples have a stable id per record (for example conversation.created:<conversation id>), so loading samples twice shows the same records. In samples, previous_status and previous_assignee are always null.
200 OK

GET /contacts/search

Contacts with this email address or phone number, newest first, at most 10. With both, a contact must match both. Without email and phone, the answer is [].
200 OK

POST /contacts

Creates a contact, with the same rules as the contact card in Keloa. When the email address’s domain belongs to one of your companies, Keloa links the contact to it.
201 Created with the new Contact:
Errors (422): none of name, email or phone (Enter a name, an email address or a phone number.), an invalid value, or an email address another contact already has (This address already belongs to <name>., in errors.email). Use Find Contact first, or Zapier’s Find or Create Contact, to avoid duplicates.

PATCH /contacts/{id}

Updates a contact. Send only the fields to change; fields you leave out or send empty keep their value.
200 OK with the updated Contact. An unknown ID answers 404.

GET /conversations/search

With id, that conversation. Otherwise the newest conversations (at most 10) of the contacts with contact_email, optionally in one status. Conversations merged into another one are never returned. Without id and contact_email, the answer is [].
200 OK

POST /conversations

Emails a contact and starts a new email conversation, like New message in the inbox. Keloa sends it from the workspace’s default mailbox, creates the contact when the address is new, and assigns the conversation to the teammate who connected. The AI agent stays out of the conversation, also when the contact answers.
201 Created with the new Conversation:
When the workspace has no verified email domain, or the email can’t be sent, Keloa still creates the conversation and keeps the message in it, but the contact doesn’t receive it. The response doesn’t say so; your team sees why in the inbox.

PATCH /conversations/{id}

Changes the status, priority, assignee or team of a conversation. Send at least one field; fields you leave out or send empty stay as they are. Each change goes through the same rules as in the inbox: the timeline, SLA clocks and notifications follow.
200 OK with the updated Conversation. Errors: 404 for an unknown conversation. 422 when no field is given, for a teammate who isn’t in the workspace or is a viewer, for an unknown team, for a status change that isn’t possible, and for a conversation that was merged into another one.

POST /conversations/{id}/replies

Replies to the contact on the conversation’s own channel (email, WhatsApp, Instagram, Messenger, Telegram, Slack or the web widget), as the teammate who connected. It’s sent right away, without the inbox’s undo window. Like a reply from the inbox, it assigns an unassigned conversation to that teammate (when the workspace assigns conversations on reply), and the AI agent stops answering in it.
201 Created
Errors: 404 for an unknown conversation. 422 for an empty content or a conversation that was merged into another one.

POST /conversations/{id}/notes

Adds an internal note as the teammate who connected. The contact never sees it. The assignee and teammates mentioned in it are notified, as for a note from the inbox.
201 Created
Errors: 402 on a plan without internal notes (Starter). 404 for an unknown conversation. 422 for an empty content or a conversation that was merged into another one.

POST /conversations/{id}/tags

Adds tags to a conversation. Tags it already has (compared case-insensitively) are skipped, and its other tags stay.
200 OK with the updated Conversation. Adding a tag also fires the conversation.tagged event. Errors: 404 for an unknown conversation. 422 without tags, with more than 20, or for a conversation that was merged into another one.

REST hooks

Keloa triggers are REST hooks. When a Zap with a Keloa trigger is turned on, Zapier subscribes a hook; when it’s turned off, Zapier unsubscribes it. In between, Keloa POSTs every matching event to the hook’s target_url.

Delivery

  • Body. One event object, see Events. X-Keloa-Delivery is the event’s id; retries of the event reuse it.
  • Where. Only https URLs on hooks.zapier.com. Keloa doesn’t follow redirects.
  • When. Events go out from a queue right after the change is saved, one delivery per hook. Conversations from testing an AI agent never fire events. Deliveries can arrive out of order, for example after a retry.
  • Timeouts. 5 seconds to connect, 15 seconds in total.

Retries and removal

Keloa also deletes a hook when:
  • hooks.zapier.com answers 50 deliveries in a row with an error status (a success resets the count);
  • its connection is revoked or disconnected (all of that connection’s hooks go);
  • the teammate who connected is no longer an owner or admin, or has left the workspace (the connection is revoked at the next delivery).

Events

Every event is a JSON object with the same envelope, followed by the event’s subjects:
A conversation is created on any channel: a contact starts one, or a teammate or a Zap starts an email.
A conversation’s status changes, by a teammate, the AI agent, a flow, a Zap or automatically. previous_status is the status before the change. A hook with a status filter gets only changes to that status.
A conversation is assigned to a teammate (also a re-assignment). Unassigning doesn’t fire it. previous_assignee is the teammate who had it before, or null.
One or more tags are added to a conversation. added_tags lists only the new tags. A hook with a tag filter gets the event only when that tag is among added_tags.
A contact rates a conversation in the satisfaction survey. rating.score is 1 to 5; rating.comment is the contact’s comment or null.
A contact writes on any channel, in a new or an existing conversation. Replies by teammates or the AI agent and internal notes don’t fire it.
A contact is created: by a message from someone new, by a teammate or by a Zap.
A teammate runs a Zap command on a conversation. command is the lowercase command name, arguments the details the teammate typed (an empty string when none), and operator the teammate who ran it. A hook with a command filter gets only that command.

Webhooks

Signed POSTs to your own endpoint on conversation events.

Members & roles

Who’s an owner or admin in your workspace.

Plans

Integration slots and internal notes per plan.

Custom HTTP tool

Let your AI agent call your own endpoints.