All integrations

Heyy

MESSAGING · MESSAGING

Workspace teams, users, conversations, and files in the account they connected.

Acts as the person, not as itself

Each user connects their own account. Every call carries both identities — the agent and the person it is acting for — so the agent can never reach past what that individual can already do.

Credentials never touch the agent

Tokens live in the vault and attach server-side at call time. The agent holds a session, not a secret, and revoking access does not mean rotating a key.

Every call on the record

Who asked, which agent acted, which action ran, and the verdict that let it through — one audit trail across every integration, not one per vendor.

What an agent can do

Each action is granted on its own. An agent allowed to read is not thereby allowed to write, and the scope beside each row is what the acting user must have connected for it to run at all.

heyy_delete_api_webhooks_by_webhookidWRITE

Delete API webhook via DELETE /api_webhooks/{webhookId}. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_attributes_by_attributeidWRITE

Delete attribute via DELETE /attributes/{attributeId}. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_campaigns_by_campaignidWRITE

Delete campaign via DELETE /campaigns/{campaignId}. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_campaigns_by_campaignid_recipientsWRITE

Remove recipients via DELETE /campaigns/{campaignId}/recipients. Names the recipients to remove in a JSON BODY -- the campaign is in the path, the recipients are not -- so this is one of only two DELETEs on this surface that sends a body. A caller that sends none removes nothing while the call still succeeds. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_chats_by_chatidWRITE

Delete chat via DELETE /chats/{chatId}. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_contacts_by_contactidWRITE

Delete contact via DELETE /contacts/{contactId}. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_contacts_by_contactid_labelsWRITE

Remove labels from contact via DELETE /contacts/{contactId}/labels. Names the labels to remove in a JSON BODY, not in the path, so this is the second of only two DELETEs on this surface that sends a body. It detaches labels from the contact and does not delete the labels themselves -- Delete label is what destroys a label for the whole workspace. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_labels_by_labelidWRITE

Delete label via DELETE /labels/{labelId}. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_message_templates_by_messagetemplateidWRITE

Delete message template via DELETE /message_templates/{messageTemplateId}. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_delete_teams_by_teamidWRITE

Delete team via DELETE /teams/{teamId}. DESTRUCTIVE and not reversible through this API: Heyy's v3 contract publishes no undelete and no recycle bin, so the only recovery is re-creating the resource.

api
heyy_get_attributes_by_attributeidREAD

Get attribute via GET /attributes/{attributeId}.

api
heyy_get_automations_by_automationidREAD

Get automation via GET /automations/{automationId}.

api
heyy_get_campaigns_by_campaignidREAD

Get campaign via GET /campaigns/{campaignId}.

api
heyy_get_channels_by_channelidREAD

Get channel via GET /channels/{channelId}.

api
heyy_get_chats_by_chatidREAD

Get chat via GET /chats/{chatId}.

api
heyy_get_contacts_by_contactidREAD

Get contact via GET /contacts/{contactId}.

api
heyy_get_files_by_fileidREAD

Get file via GET /files/{fileId}. Reads a file record that already exists in the workspace. UPLOADING is not part of this integration: Heyy's `POST /files` is a multipart binary upload and is withheld, so a `fileId` referenced by the message, template and campaign tools has to be created in the Heyy app or by calling that endpoint outside Agentic Fabriq.

api
heyy_get_files_by_fileid_public_urlREAD

Get public file URL via GET /files/{fileId}/public_url. Returns a stable public URL for an uploaded file, creating one if it does not exist yet. Use this URL when referencing the file by URL (for example, in automation template media overrides). The URL does not expire.

api
heyy_get_journeys_by_journeyidREAD

Get journey via GET /journeys/{journeyId}.

api
heyy_get_labels_by_labelidREAD

Get label via GET /labels/{labelId}.

api
heyy_get_message_templates_by_messagetemplateidREAD

Get message template via GET /message_templates/{messageTemplateId}.

api
heyy_get_teams_by_teamidREAD

Get team via GET /teams/{teamId}.

api
heyy_get_usersREAD

Get users via GET /users. Returns the workspace's members. This is a plain GET rather than a `POST /users/search`, so it takes no filter, sort or page arguments at all -- the two listings that behave this way are users and workspace.

api
heyy_get_users_by_useridREAD

Get user via GET /users/{userId}.

api
heyy_get_workspaceREAD

Get workspace via GET /workspace. Returns the workspace associated with the API key. Takes no arguments and is the cheapest read on the surface, which is why it is also what Agentic Fabriq probes a pasted API key with: the key identifies its own workspace, so there is nothing to select.

api
heyy_post_api_webhooksWRITE

Create API webhook via POST /api_webhooks. Registers a URL Heyy will POST workspace events to. The delivery target is the customer's own endpoint, so anything this webhook is pointed at receives Heyy's event payloads -- including message content -- until the webhook is deleted.

api
heyy_post_api_webhooks_searchWRITE

Search API webhooks via POST /api_webhooks/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_attributesWRITE

Create attribute via POST /attributes.

api
heyy_post_attributes_searchWRITE

Search attributes via POST /attributes/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_automations_by_automationid_pauseWRITE

Pause automation via POST /automations/{automationId}/pause.

api
heyy_post_automations_by_automationid_triggerWRITE

Trigger automation via POST /automations/{automationId}/trigger. Starts an automation for a contact, with input parameters. Heyy names this as the SAFER way to reach a contact than sending directly: an automation can carry a subscription condition, while the message tools check nothing. What the automation then does -- including sending -- is configured in Heyy, not here, so the effect of this call is whatever that automation is built to do.

api
heyy_post_automations_by_automationid_unpauseWRITE

Unpause automation via POST /automations/{automationId}/unpause.

api
heyy_post_automations_searchWRITE

Search automations via POST /automations/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_campaignsWRITE

Create campaign via POST /campaigns.

api
heyy_post_campaigns_by_campaignid_recipientsWRITE

Add recipients via POST /campaigns/{campaignId}/recipients.

api
heyy_post_campaigns_by_campaignid_startWRITE

Start campaign via POST /campaigns/{campaignId}/start. Starts the campaign SENDING. This is the point of no return for a broadcast: every recipient currently on the campaign is messaged, the sends are billed as message credits, and nothing in this API unsends them. Read the campaign and its recipients back before calling it.

api
heyy_post_campaigns_searchWRITE

Search campaigns via POST /campaigns/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_channels_searchWRITE

Search channels via POST /channels/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_chats_by_chatid_assign_teamWRITE

Assign chat to team via POST /chats/{chatId}/assign_team.

api
heyy_post_chats_by_chatid_assign_userWRITE

Assign chat to user via POST /chats/{chatId}/assign_user.

api
heyy_post_chats_by_chatid_mark_as_not_sensitiveWRITE

Mark chat as not sensitive via POST /chats/{chatId}/mark_as_not_sensitive. Clears the sensitive flag, which WIDENS who on the team can read the conversation. It is the reverse of Mark chat as sensitive and is not classified destructive, but it does expose a chat that somebody deliberately restricted.

api
heyy_post_chats_by_chatid_mark_as_readWRITE

Mark chat as read via POST /chats/{chatId}/mark_as_read.

api
heyy_post_chats_by_chatid_mark_as_sensitiveWRITE

Mark chat as sensitive via POST /chats/{chatId}/mark_as_sensitive. Flags the conversation as containing sensitive information, which is a visibility control inside Heyy rather than a note: it restricts who on the team can read the chat.

api
heyy_post_chats_by_chatid_mark_as_unreadWRITE

Mark chat as unread via POST /chats/{chatId}/mark_as_unread.

api
heyy_post_chats_by_chatid_statusWRITE

Change chat status via POST /chats/{chatId}/status.

api
heyy_post_chats_searchWRITE

Search chats via POST /chats/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_contactsWRITE

Create contact via POST /contacts.

api
heyy_post_contacts_bulkWRITE

Bulk upsert contacts via POST /contacts/bulk. Upserts many contacts in one call, with the same match-by-identifier behaviour as Upsert contact. A partial failure is reported by Heyy in the response rather than raised here, so read the result instead of treating a 200 as "all rows landed".

api
heyy_post_contacts_by_contactid_labelsWRITE

Add labels to contact via POST /contacts/{contactId}/labels. Attaches existing labels to the contact. It does not create a label -- Create label does that -- and labels are what the campaign and search tools filter audiences on, so adding one can change who a scheduled campaign reaches.

api
heyy_post_contacts_by_contactid_subscribeWRITE

Subscribe contact via POST /contacts/{contactId}/subscribe.

api
heyy_post_contacts_by_contactid_unsubscribeWRITE

Unsubscribe contact via POST /contacts/{contactId}/unsubscribe. Records that the contact has opted out. It does not by itself stop the message tools: Send message and Send template message deliver to an unsubscribed contact, because Heyy makes the consent check the caller's responsibility.

api
heyy_post_contacts_searchWRITE

Search contacts via POST /contacts/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_contacts_upsertWRITE

Upsert contact via POST /contacts/upsert. Creates the contact or MATCHES an existing one by identifier (phone number or email) and updates it. This is the tool to use when the identifier may already exist -- Create contact fails on a duplicate, and Update contact cannot change a phone number or an email at all.

api
heyy_post_journeys_by_journeyid_subscribeWRITE

Subscribe contacts to journey via POST /journeys/{journeyId}/subscribe. Adds contacts to a journey, which may begin messaging them immediately depending on how the journey is built in Heyy.

api
heyy_post_journeys_by_journeyid_unsubscribeWRITE

Unsubscribe contacts from journey via POST /journeys/{journeyId}/unsubscribe.

api
heyy_post_journeys_searchWRITE

Search journeys via POST /journeys/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_labelsWRITE

Create label via POST /labels.

api
heyy_post_labels_searchWRITE

Search labels via POST /labels/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_message_templatesWRITE

Create message template via POST /message_templates.

api
heyy_post_message_templates_searchWRITE

Search message templates via POST /message_templates/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_post_messages_sendWRITE

Send message via POST /messages/send. Sends a free-form message on a channel the workspace has already connected. TWO THINGS THIS SPENDS THAT NO OTHER TOOL DOES. It contacts a real person, and on WhatsApp it consumes message credits, which Heyy bills on top of the plan -- there is no dry run. And consent is the CALLER's job: Heyy's own reference states that for a MARKETING message "you are responsible for confirming the contact is subscribed before you call it. The message will be sent even if the contact is unsubscribed." Check `isSubscribed` with Get contact first, or use Trigger automation, which Heyy names as the path where a subscription condition can gate the send. Free-form replies also stop working once the channel's conversation window has closed; that is when a template message is the only form that will deliver.

api
heyy_post_messages_send_templateWRITE

Send template message via POST /messages/send_template. Sends a pre-approved template message, which is what reaches a contact AFTER the channel's free-form conversation window has closed. The same consent rule applies verbatim: for a MARKETING message "you are responsible for confirming the contact is subscribed before you call it. The message will be sent even if the contact is unsubscribed." WhatsApp templates are approved by Meta rather than by Heyy, so a template that is not approved for the channel fails at Heyy's end rather than here, and the same message credits are spent.

api
heyy_post_teamsWRITE

Create team via POST /teams.

api
heyy_post_teams_searchWRITE

Search teams via POST /teams/search. This is a LIST endpoint even though it is a POST: filtering (`query`), ordering (`sortBy`), free-text matching (`search`) and paging (`pagination`, zero-based `page` with a `limit` of 1-100, default 10) all travel in the request body, and the response wraps the rows in `data` with a `pagination.total`. Send an empty body to get the first page unfiltered.

api
heyy_put_api_webhooks_by_webhookidWRITE

Update API webhook via PUT /api_webhooks/{webhookId}.

api
heyy_put_attributes_by_attributeidWRITE

Update attribute via PUT /attributes/{attributeId}.

api
heyy_put_campaigns_by_campaignidWRITE

Update campaign via PUT /campaigns/{campaignId}.

api
heyy_put_contacts_by_contactidWRITE

Update contact via PUT /contacts/{contactId}. Updates contact profile fields (first name, last name, and custom attributes). Phone number and email cannot be changed here — use upsert to create or match by identifier.

api
heyy_put_labels_by_labelidWRITE

Update label via PUT /labels/{labelId}.

api
heyy_put_message_templates_by_messagetemplateidWRITE

Update message template via PUT /message_templates/{messageTemplateId}.

api
heyy_put_teams_by_teamidWRITE

Update team via PUT /teams/{teamId}.

api

Put Heyy behind one governed endpoint.

Same permissions, same audit trail, whatever else you connect next.