Sense6 API
Read and act on mail, tasks, contacts, calendar, docs and chat from your own code, Zapier or another AI app. Every request acts as the person whose token it uses, with exactly their access.
- In Sense6, open Settings → API tokens and create a token. Choose read only if the app only needs to look.
- Send it with every request as a bearer token:
curl -H "Authorization: Bearer $SENSE6_TOKEN" https://sense6.io/api/v1/me
Base URL: https://sense6.io/api/v1 · OpenAPI 3.1
Authentication
Tokens start with s6_ and are shown once, when you make them. A full-access token can do what its owner can: send email, create and change things. A read-only token can only look; changes answer 403 read_only_token. Revoke a token in Settings and every app using it loses access at once, along with its webhooks.
Sense6 stores only a hash of each token. Changes made through the API are recorded in the workspace's audit log as done through the API.
Responses and errors
Everything is JSON. One item comes back as { data }; lists as { data, next_cursor }. To get the next page, send next_cursor back as ?cursor= until it's null.
Each token can make 300 requests a minute. Every response says how many are left in X-RateLimit-Remaining; past the limit you get 429 with Retry-After.
400 | invalid_request | Something in the request isn't right; the message says what. |
401 | unauthorized | No token, or it was revoked. |
403 | read_only_token / forbidden | The token is read-only, or its owner can't do that. |
404 | not_found | It doesn't exist, or its owner can't open it. |
409 | conflict | It changed since you read it. |
415 | unsupported_media_type | Send JSON with Content-Type: application/json. |
429 | rate_limited | Too many requests; wait Retry-After seconds. |
503 | ai_unavailable | Sense6's AI can't answer right now. |
{ "error": { "code": "not_found", "message": "Task not found." } }Account
Who the token acts for.
/api/v1/meWho the token acts for
Returns: Me
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/me"
Read, send and sort email in the token owner's mailbox.
/api/v1/messagesList email
Newest first. Reading the list doesn't mark anything read.
folder | string | Which folder (default inbox). One of: inbox, sent, drafts, archive, deleted, junk, snoozed. |
bucket | string | Only what Sense6 sorted this way. One of: needs_you, fyi, done, untriaged. |
q | string | Words to look for. |
unread | boolean | Only unread email. |
since | date-time | Only email that arrived after this. |
limit | integer | How many to return (default 50, at most 200). |
cursor | string | next_cursor from the previous page. |
Returns: a page of Message
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/messages"
/api/v1/messages/{id}Get an email
idrequired | string | The item's id. |
include | string | html adds the HTML body. One of: html. |
Returns: Message
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/messages/abc123"
/api/v1/messagesFull-access tokenSend an email
Sent from the token owner's address, like email written in Sense6. With draft: true it's saved in Drafts instead.
torequired | string[] | Recipients. |
cc | string[] | Copied. |
bcc | string[] | Blind copies. |
subject | string | The subject. |
text | string | The message, as plain text. |
html | string | The message as HTML (the text is made from it). |
reply_to_id | string | A message this replies to (it joins that conversation). |
draft | boolean | Save it in Drafts instead of sending. |
Returns: SentMessage
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"to":["[email protected]"],"subject":"Proposal","text":"Hi Dana, here'\''s the proposal."}' \
https://sense6.io/api/v1/messages/api/v1/messages/{id}Full-access tokenMark, move or sort an email
idrequired | string | The item's id. |
read | boolean | Mark it read or unread. |
folder | string | Move it. One of: inbox, archive, deleted. |
bucket | string | Sort it. One of: needs_you, fyi, done. |
Returns: Message
curl -X PATCH -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{}' \
https://sense6.io/api/v1/messages/abc123Tasks
Tasks assigned to you, ones you gave others, and finished ones.
/api/v1/tasksList tasks
filter | string | mine: assigned to you (default); assigned: ones you gave others; all: every open task you can see. One of: mine, assigned, all. |
status | string | open (default) or done. One of: open, done. |
q | string | Only tasks with these words in the title or notes. |
limit | integer | How many to return (default 50, at most 200). |
cursor | string | next_cursor from the previous page. |
Returns: a page of Task
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/tasks"
/api/v1/tasks/{id}Get a task
idrequired | string | The item's id. |
Returns: Task
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/tasks/abc123"
/api/v1/tasksFull-access tokenCreate a task
titlerequired | string | What to do. |
notes | string | Details. |
due | date | The day it's due. |
assignee_email | string | Someone in your workspace to give it to (default: you). |
Returns: Task
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Send the signed lease","due":"2026-10-01"}' \
https://sense6.io/api/v1/tasks/api/v1/tasks/{id}Full-access tokenChange or finish a task
idrequired | string | The item's id. |
title | string | What to do. |
notes | string | Details. |
due | date | The day it's due (null clears it). |
assignee_email | string | Give it to someone else in your workspace. |
status | string | done or open. One of: open, done. |
Returns: Task
curl -X PATCH -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{}' \
https://sense6.io/api/v1/tasks/abc123/api/v1/tasks/{id}Full-access tokenDelete a task
idrequired | string | The item's id. |
Returns: 204 No Content
curl -X DELETE -H "Authorization: Bearer $SENSE6_TOKEN" \ https://sense6.io/api/v1/tasks/abc123
Contacts
Your contacts, including the ones synced from connected accounts.
/api/v1/contactsList contacts
q | string | Name, email, phone, company or tag. |
tag | string | Only contacts with this tag. |
limit | integer | How many to return (default 50, at most 200). |
cursor | string | next_cursor from the previous page. |
Returns: a page of Contact
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/contacts"
/api/v1/contacts/{id}Get a contact (with recent activity)
idrequired | string | The item's id. |
Returns: Contact
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/contacts/abc123"
/api/v1/contactsFull-access tokenAdd a contact
With an email address you already have, the details are added to that person (merged: true in the response).
name | string | Their name. |
email | string | An email address (or emails: a list). |
phone | string | A phone number (or phones: a list). |
company | string | Company. |
job_title | string | Job title. |
notes | string | Notes. |
tags | string[] | Tags. |
starred | boolean | Star them. |
Returns: Contact
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Dana Kim","email":"[email protected]"}' \
https://sense6.io/api/v1/contacts/api/v1/contacts/{id}Full-access tokenChange a contact
Send only the fields to change (the same ones as when adding). Synced contacts only take notes, tags and the star.
idrequired | string | The item's id. |
Returns: Contact
curl -X PATCH -H "Authorization: Bearer $SENSE6_TOKEN" \ https://sense6.io/api/v1/contacts/abc123
/api/v1/contacts/{id}Full-access tokenDelete a contact
idrequired | string | The item's id. |
Returns: 204 No Content
curl -X DELETE -H "Authorization: Bearer $SENSE6_TOKEN" \ https://sense6.io/api/v1/contacts/abc123
Calendar
Meetings and events from Sense6 and connected calendars, with their notes.
/api/v1/eventsList meetings and events
from | date-time | Start of the range (default now). |
to | date-time | End of the range (default 30 days after from). |
limit | integer | How many to return (default 50, at most 200). |
cursor | string | next_cursor from the previous page. |
Returns: a page of Event
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/events"
/api/v1/events/{id}Get an event with its notes and transcript
idrequired | string | The item's id. |
Returns: Event
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/events/abc123"
/api/v1/eventsFull-access tokenCreate a meeting
People in the workspace are added to it. With send_invites (the default when there are attendees), calendar invitations go out from the owner's connected Microsoft 365 or Google calendar.
title | string | Its title. |
startrequired | date-time | When it starts. |
endrequired | date-time | When it ends. |
attendees | string[] | Email addresses to invite. |
location | string | Where. |
description | string | The agenda. |
send_invites | boolean | Send calendar invitations. |
online_meeting | boolean | Add a Teams or Meet link to the invitation. |
Returns: Event
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Kickoff","start":"2026-10-01T15:00:00Z","end":"2026-10-01T15:30:00Z"}' \
https://sense6.io/api/v1/events/api/v1/events/{id}Full-access tokenDelete an event
It's deleted from the calendar it came from too; upcoming ones are cancelled for the guests. Events on someone else's calendar are only hidden for you.
idrequired | string | The item's id. |
Returns: Event
curl -X DELETE -H "Authorization: Bearer $SENSE6_TOKEN" \ https://sense6.io/api/v1/events/abc123
Docs
Documents you can open, and new ones from Markdown.
/api/v1/docsList documents
wiki | boolean | Only the workspace wiki. |
limit | integer | How many to return (default 50, at most 200). |
cursor | string | next_cursor from the previous page. |
Returns: a page of Doc
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/docs"
/api/v1/docs/{id}Get a document with its text
idrequired | string | The item's id. |
Returns: Doc
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/docs/abc123"
/api/v1/docsFull-access tokenCreate a document
title | string | Its title. |
text | string | Its content, as Markdown. |
wiki | boolean | Put it in the workspace wiki (everyone can read it). |
Returns: Doc
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Meeting notes","text":"# Notes\n\n- Ship Friday"}' \
https://sense6.io/api/v1/docsChat
Channels and direct messages.
/api/v1/channelsList channels
limit | integer | How many to return (default 50, at most 200). |
cursor | string | next_cursor from the previous page. |
Returns: a page of Channel
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/channels"
/api/v1/channels/{id}/messagesLatest messages in a channel
idrequired | string | The item's id. |
limit | integer | How many (default 50, at most 200). |
Returns: a page of ChatMessage
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/channels/ch_123/messages"
/api/v1/channels/{id}/messagesFull-access tokenPost a message
idrequired | string | The item's id. |
textrequired | string | What to say. |
parent_id | string | Reply in this message's thread. |
Returns: ChatMessage
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"Deploy is done ✅"}' \
https://sense6.io/api/v1/channels/ch_123/messagesPipeline
Deals in the workspace's sales pipeline.
/api/v1/dealsList deals
stage | string | Only deals in this stage (its id). |
q | string | Words in the name, company, people or next step. |
email | string | Only deals with this person. |
mine | boolean | Only deals you own. |
limit | integer | How many to return (default 50, at most 200). |
cursor | string | next_cursor from the previous page. |
Returns: a page of Deal
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/deals"
/api/v1/deals/{id}Get a deal
idrequired | string | The item's id. |
Returns: Deal
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/deals/abc123"
/api/v1/dealsFull-access tokenAdd a deal
Shared with the workspace unless private.
titlerequired | string | Its name. |
value | integer | Its value, in cents. |
currency | string | Three-letter code (default USD). |
stage | string | A stage id (default: the first open stage). |
company | string | The company. |
people | string[] | Email addresses of the people involved. |
owner_id | string | Who owns it (default: you). |
close_date | date | Expected close date. |
next_step | string | The next step. |
notes | string | Notes. |
private | boolean | Only you and the owner see it. |
Returns: Deal
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"123 Main St listing","value":45000000,"people":["[email protected]"]}' \
https://sense6.io/api/v1/deals/api/v1/deals/{id}Full-access tokenMove or change a deal
Send only what changes (the same fields as when adding, plus lost_reason). Changing stage fires deal.stage_changed (and deal.won or deal.lost).
idrequired | string | The item's id. |
Returns: Deal
curl -X PATCH -H "Authorization: Bearer $SENSE6_TOKEN" \ https://sense6.io/api/v1/deals/abc123
/api/v1/deals/{id}Full-access tokenDelete a deal
idrequired | string | The item's id. |
Returns: 204 No Content
curl -X DELETE -H "Authorization: Bearer $SENSE6_TOKEN" \ https://sense6.io/api/v1/deals/abc123
Search and AI
Search everything, or ask Sense6.
/api/v1/searchSearch everything
qrequired | string | What to look for. |
limit | integer | How many (default 20, at most 50). |
Returns: a page of SearchHit
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/search?q=pricing"
/api/v1/askFull-access tokenAsk Sense6
Sense6 answers from what the token's owner can see, and can do what they ask. Anything it would send or post waits for their approval in Sense6. Uses their AI allowance.
questionrequired | string | The question or request. |
Returns: Answer
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"question":"What did we decide about pricing last week?"}' \
https://sense6.io/api/v1/askWebhooks
Get a signed POST when something happens (how Zapier triggers work).
/api/v1/hooksList this token's webhooks
Returns: a page of Hook
curl -H "Authorization: Bearer $SENSE6_TOKEN" \ "https://sense6.io/api/v1/hooks"
/api/v1/hooksSubscribe to events
Works with read-only tokens too: a subscription only hears about what the token's owner can see.
urlrequired | string | An https URL to POST events to. |
eventsrequired | string[] | Events to hear (see the list below). |
Returns: Hook
curl -X POST -H "Authorization: Bearer $SENSE6_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/sense6","events":["task.created"]}' \
https://sense6.io/api/v1/hooks/api/v1/hooks/{id}Unsubscribe
idrequired | string | The item's id. |
Returns: 204 No Content
curl -X DELETE -H "Authorization: Bearer $SENSE6_TOKEN" \ https://sense6.io/api/v1/hooks/abc123
Objects
Me
The person a token acts for.
id | string | Their user id. |
name | string | Their name. |
email | string | Their email address. |
role | string | member, admin or guest. |
time_zone | string | IANA time zone, like America/New_York. |
workspace | object | The workspace: { id, name }. |
token | object | This token: { scope: "read" | "write" }. |
Message
An email.
id | string | The message id. |
thread_id | string | The conversation it belongs to. |
folder | string | inbox, sent, drafts, archive, deleted or junk. |
subject | string | The subject line. |
from | object | { name, email }. |
to | object[] | Recipients: [{ name, email }]. |
cc | object[] | Copied: [{ name, email }]. |
received_at | date-time | When it arrived (or was sent). |
is_read | boolean | Whether it's been read. |
bucket | string | How Sense6 sorted it: needs_you, fyi or done. Can be null. |
snippet | string | The start of the text. |
has_attachments | boolean | Whether it has files attached. |
attachments | object[] | [{ name, content_type, size }]. |
text | string | The full text (one message only). |
html | string | The HTML body, with ?include=html (one message only). Can be null. |
url | string | Opens it in Sense6. |
SentMessage
What happened to an email you sent.
id | string | The sent message (or the draft). |
status | string | sent, draft or failed (an outside address didn't accept it). |
delivery | string | How outside delivery went. Can be null. |
external | string[] | Recipients outside the workspace. |
Task
A task.
id | string | The task id. |
title | string | What to do. |
notes | string | Details. |
status | string | open or done. |
due | date | The day it's due. Can be null. |
assignee | object | { id, name } of who it's for. Can be null. |
created_by | object | { id, name } of who made it. Can be null. |
created_at | date-time | When it was made. |
completed_at | date-time | When it was finished. Can be null. |
url | string | Opens it in Sense6. |
Contact
A person in your contacts.
id | string | The contact id. |
name | string | Their name. |
emails | object[] | [{ address, label }]. |
phones | object[] | [{ number, label }]. |
company | string | Company. |
job_title | string | Job title. |
addresses | string[] | Postal addresses. |
websites | string[] | Websites. |
birthday | string | Birthday. Can be null. |
notes | string | Your notes. |
tags | string[] | Your tags. |
starred | boolean | Starred. |
sources | string[] | Where it comes from: sense6, google, m365, icloud… |
editable | boolean | All fields can be changed (false: synced, only notes, tags and the star). |
colleague | boolean | Someone in your workspace. |
url | string | Opens it in Sense6. |
Event
A meeting or calendar event.
id | string | The event id. |
title | string | Its title. |
start | date-time | When it starts. |
end | date-time | When it ends. |
all_day | boolean | An all-day event. |
location | string | Where. |
join_url | string | The video call link. Can be null. |
source | string | sense6, or calendar (from a connected calendar). |
organizer | object | { name, email }. Can be null. |
attendees | object[] | [{ name, email, response, guest }]. |
description | string | Agenda or description. |
has_notes | boolean | Sense6 wrote notes for it. |
notes | object | { summary, decisions, action_items } (one event only). Can be null. |
transcript | string | The transcript (one event only). Can be null. |
url | string | Opens it in Sense6. |
Doc
A document.
id | string | The document id. |
title | string | Its title. |
wiki | boolean | In the workspace wiki. |
created_at | date-time | When it was made. |
updated_at | date-time | When it last changed. |
text | string | Its text, as Markdown (one document only). |
url | string | Opens it in Sense6. |
Channel
A chat channel or direct message.
id | string | The channel id. |
kind | string | channel or dm. |
visibility | string | public or private. |
name | string | Its name. |
title | string | How it's shown: #name, or the people in a direct message. |
topic | string | Its topic. |
unread | integer | Messages you haven't read. |
last_message_at | date-time | The latest message. Can be null. |
url | string | Opens it in Sense6. |
ChatMessage
A chat message.
id | string | The message id. |
channel_id | string | Its channel. |
text | string | What it says. |
author | object | { id, name }. |
sent_at | date-time | When it was posted. |
edited_at | date-time | When it was last edited. Can be null. |
parent_id | string | The thread it replies to. Can be null. |
reply_count | integer | Replies in its thread. |
reactions | object | Emoji → the ids of who reacted. |
Deal
A deal in the pipeline.
id | string | The deal id. |
title | string | Its name. |
stage | object | { id, name, kind (open, won or lost), probability }. |
value | integer | Its value, in cents. |
currency | string | Three-letter currency code. |
company | string | The company. |
people | string[] | Email addresses of the people involved. |
owner | object | { id, name }. |
close_date | date | Expected close date. Can be null. |
next_step | string | The next step. |
notes | string | Notes. |
private | boolean | Only its creator and owner see it. |
lost_reason | string | Why it was lost. Can be null. |
suggestion | object | What Sense6 suggests from recent email and meetings: { stage, next_step, close_date, summary }. Can be null. |
stage_changed_at | date-time | When it last changed stage. |
closed_at | date-time | When it was won or lost. Can be null. |
created_at | date-time | When it was added. |
updated_at | date-time | When it last changed. |
url | string | Opens it in Sense6. |
SearchHit
Something search found.
id | string | The item's id. |
kind | string | message, document, sheet, meeting, task, person or file. |
title | string | Its title. |
snippet | string | Where the words were found. |
url | string | Opens it in Sense6. Can be null. |
Answer
Sense6's answer.
answer | string | The answer, as Markdown. |
links | object[] | What it used or made: [{ label, href }]. |
approvals_waiting | integer | Actions waiting for the person's approval in Sense6. |
Hook
A webhook subscription.
id | string | The subscription id. |
url | string | Where events are sent. |
events | string[] | The events it hears. |
created_at | date-time | When it was made. |
secret | string | The signing secret (only when it's made). |
Webhook events
Subscribe with POST /api/v1/hooks. Sense6 then POSTs each event to your URL as JSON, and only tells you about what the token's owner can see. A delivery that fails is retried with backoff, up to 8 times over about a day. Workspace admins can also send every event in the workspace to an endpoint from Admin → Webhooks.
mail.received | Mail arrived in someone's inbox |
mail.sent | Someone sent mail |
task.created | A task was created |
task.completed | A task was completed |
meeting.created | A meeting was created |
meeting.notes_ready | Meeting notes were generated |
doc.created | A document was created |
approval.requested | An agent action is waiting for approval |
chat.message | A chat message was posted |
member.joined | Someone joined the workspace |
form.response | Someone answered a form |
booking.created | Someone booked a time through a booking link |
contact.created | Someone added a contact |
deal.created | A deal was added to the pipeline |
deal.stage_changed | A deal moved to another stage |
deal.won | A deal was won |
deal.lost | A deal was lost |
Each delivery looks like this. data holds the event's details and the item's id: fetch the item from the API for everything else.
{
"id": "evt_3f2a…",
"event": "task.created",
"createdAt": "2026-10-01T15:04:05.000Z",
"workspace": "tenant_…",
"data": {
"id": "task_…",
"title": "Send the signed lease",
"assigneeId": "user_…",
"due": "2026-10-03",
"createdBy": "user_…"
}
}Headers: X-Sense6-Event, X-Sense6-Delivery, X-Sense6-Timestamp and X-Sense6-Signature. Check the signature with the secret you got when subscribing:
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received (before JSON.parse).
export function isFromSense6(headers, rawBody, secret) {
const ts = headers["x-sense6-timestamp"];
const sig = headers["x-sense6-signature"] ?? "";
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // older than 5 minutes
const expected = "sha256=" + createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
return sig.length === expected.length && timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}Zapier
Connect Sense6 to thousands of apps without code. Triggers: new email, new or finished task, new meeting, meeting notes ready, new document, new contact, new deal or deal stage change, new chat message and new form response. Actions: send an email, create a task, contact, meeting, deal or document, update a deal, post in chat, and ask Sense6.
The Sense6 app for Zapier is on its way. Until then, use Zapier's Webhooks and API request steps with a token.
MCP
AI apps that speak the Model Context Protocol (Claude, ChatGPT, Cursor and others) can use Sense6's tools directly, with the same tokens. Anything they would send or post waits for approval in Sense6.
{
"mcpServers": {
"sense6": {
"url": "https://sense6.io/api/mcp",
"headers": {
"Authorization": "Bearer s6_…"
}
}
}
}