The API is plain REST and JSON. One header, no OAuth, no token refresh. You need an integration key; see Connect Joyn to Zapier or another tool for how to create one.
The base URL is https://api.getjoyn.io/api. The full reference, generated from the API itself, is at getjoyn.io/integrations/api, and the OpenAPI document is at /v1/integrations/openapi.json on the same host.
1. Check the key
Send the key as a bearer token:
Authorization: Bearer joyn_sk_your_key_here
Call GET /v1/integrations/me. The response describes the key: its name, the space it belongs to and, for a group key, the group. Keep the space id; the space-level endpoints need it.
2. Find where the key can act
- GET /v1/integrations/groups lists the groups the key is a member of. A space key that has not been added to any group gets an empty list.
- GET /v1/integrations/group-channels lists the channels it can reach, with each channel's type. Messages go to MESSAGE or ANNOUNCEMENT channels, to-dos to TODO channels, and the kanban endpoints need KANBAN.
Read ids from these calls rather than copying them from the app, so the integration keeps working when someone renames or recreates a channel.
3. Do something
- POST /v1/channels/:id/messages posts a message as the bot. It appears immediately, marked as a bot.
- POST /v1/channels/:id/todos adds a to-do, or a sub-task when you pass a parent id.
- POST /v1/spaces/:id/events creates an event. Pass the group id; without it the request needs a permission keys do not hold.
- POST /v1/spaces/:id/email-invitations invites someone by email. Space keys only.
- The kanban endpoints read a board and its cards, move a card, and comment on it. Boards live in groups, so only a group key can reach them.
Conventions
- Ids in lists are integers, message ids are strings. Message ids are 64-bit snowflakes. Never parse one into a number; values above 2^53 lose precision silently.
- Every list is paginated the same way. You get rows plus a cursor. Pass it back as next_page to continue. The limit defaults to 100 and caps at 100.
- Timestamps are ISO-8601 with a timezone. A date-only value is rejected: 2026-09-15 fails, 2026-09-15T14:00:00.000Z works.
- Omit optional fields, do not send them empty. An empty string is not a valid date or note.
Errors
- 400 - the body or query failed validation. Check formats first.
- 401 - the key is unknown, was regenerated, or its integration was deleted.
- 403 ROUTE_NOT_PERMITTED - valid key, but this endpoint is not part of the API surface.
- 403 GROUP_SCOPED_KEY - a group key tried to do something space-level, such as inviting.
- 403 without a code - the key is not in the group, or the space withholds the permission the action needs.
- 404 - the target does not exist, or is outside what this key can reach.
Limits to design around
- Retries can duplicate writes. There are no idempotency keys yet. If a request times out but succeeded, retrying creates a second message, to-do or event. Prefer triggers that fire once.
- There are no triggers or webhooks. The API is one directional.
- Keys never expire. Rotate them on the schedule you use for any other credential.
- Rate limits are not published yet. Stay well below anything that looks like a burst. Limits will be announced before they are enforced.