Skip to content

API Overview & Conventions ​

The Chatter API is hosted by us. It has two parts:

PartURLUsed for
RESThttps://api.chatter.maragato.ca/v1Sign-up, profile, friends, history, uploads, all writes that are not real-time
WebSocketwss://api.chatter.maragato.ca/v1/wsSending messages, receiving events in real time, receipts, typing, presence

The complete REST contract is in the API Reference (download openapi.yaml to generate a client). The WebSocket protocol is in Real-time.

Workspaces and credentials ​

Your invitation email contains two values:

CredentialFormatWhere it goes
clientKeyck_…In your app. Sent on every request. Identifies your workspace. Not secret.
clientSecretcs_…Never in your app. Only for the developer endpoints (APNs setup, test users, reset), from your own machine.

A workspace is your private copy of Chatter. All users, friendships, conversations, and messages created with your clientKey exist only in your workspace. When we test your app, we create our users in your workspace too.

Required headers ​

HeaderRequired onExample
X-Client-KeyEvery request except /healthzX-Client-Key: ck_4f9a2c…
AuthorizationEvery request except /auth/*, /usernames/*, /healthz, /developer/*Authorization: Bearer eyJhbGciOi…
X-Client-Secret/developer/* onlyX-Client-Secret: cs_8b1d…
Content-TypeRequests with a bodyapplication/json
Idempotency-KeyOptional, on POST that creates resourcesIdempotency-Key: 6f1c2c1e-…

Requests without a valid X-Client-Key fail with 401 CLIENT_KEY_INVALID.

Conventions ​

  • Format: JSON, UTF-8, field names in camelCase. Unknown fields may be added at any time — ignore them.
  • IDs: ULID strings, 26 characters, for example 01JB8Z3K6Q4M2X7YV9R0T5N1PA.
  • Timestamps: ISO 8601 UTC with milliseconds, for example 2026-10-22T14:03:11.482Z.
  • Phone numbers: E.164, for example +6580000001.
  • Usernames: 3–20 characters, lowercase letters, digits, and _, starting with a letter. Unique per workspace. Case-insensitive.

Pagination ​

Lists use cursors:

json
{
  "data": [ … ],
  "page": { "nextCursor": "eyJzIjo0MjB9", "hasMore": true }
}

Pass ?cursor=<nextCursor> for the next page. limit defaults to 50, maximum 100. Message history uses beforeSeq / afterSeq instead — see Messages.

Idempotency ​

  • Messages: every send has a clientMessageId (UUID v4) that you generate. Sending the same clientMessageId again returns the original message. It never creates a duplicate.
  • Other creates: add Idempotency-Key: <uuid>. A repeated key within 24 hours returns the original response.

Tokens ​

TokenLifetimeNotes
Access token (JWT)15 minutesSend as Authorization: Bearer ….
Refresh token (opaque)30 daysSingle use. Every refresh returns a new refresh token. Reusing an old one logs the device out.

Store both in the Keychain. See Authentication.

Environments ​

There is one environment for the challenge. It never sends SMS: the verification code is always 000000.

Health ​

bash
curl https://api.chatter.maragato.ca/v1/healthz
# {"status":"ok","version":"1.0.0"}

Versioning ​

Breaking changes go to /v2. Within /v1 we only add fields, endpoints, and event types. Your app must ignore unknown fields and unknown WebSocket event types.

Where to go next ​

Questions? Reply to your invitation email.