Skip to content

Quickstart with curl ​

This walkthrough runs the same scenario as our test plan — two users sign up, become friends, and chat — using only curl and jq. Run it before you write app code, to see every response shape.

0. Setup ​

bash
export API=https://api.chatter.maragato.ca/v1
export CK=ck_your_client_key_here     # from your invitation email

1. Ana signs up ​

bash
curl -s -X POST $API/auth/otp -H "X-Client-Key: $CK" \
  -H 'Content-Type: application/json' -d '{"phone":"+6580000001"}'
# 204 No Content

ANA=$(curl -s -X POST $API/auth/verify -H "X-Client-Key: $CK" \
  -H 'Content-Type: application/json' \
  -d '{"phone":"+6580000001","code":"000000","device":{"platform":"ios","name":"curl"}}')
echo $ANA | jq '{isNewUser, profileComplete: .user.profileComplete}'
# { "isNewUser": true, "profileComplete": false }

export ANA_TOKEN=$(echo $ANA | jq -r .accessToken)

Complete the profile:

bash
curl -s "$API/usernames/ana_souza/availability" -H "X-Client-Key: $CK" | jq
# { "username": "ana_souza", "available": true }

curl -s -X PATCH $API/me -H "X-Client-Key: $CK" -H "Authorization: Bearer $ANA_TOKEN" \
  -H 'Content-Type: application/json' -d '{"displayName":"Ana Souza","username":"ana_souza"}' | jq
# { "id": "01JB…", "displayName": "Ana Souza", "username": "ana_souza", "profileComplete": true, … }

2. Ben signs up ​

bash
BEN=$(curl -s -X POST $API/auth/verify -H "X-Client-Key: $CK" \
  -H 'Content-Type: application/json' \
  -d '{"phone":"+6580000002","code":"000000","device":{"platform":"ios","name":"curl"}}')
export BEN_TOKEN=$(echo $BEN | jq -r .accessToken)

curl -s -X PATCH $API/me -H "X-Client-Key: $CK" -H "Authorization: Bearer $BEN_TOKEN" \
  -H 'Content-Type: application/json' -d '{"displayName":"Ben Tan","username":"ben_tan"}' > /dev/null

(You can skip POST /auth/otp in scripts. It is required in the app flow.)

3. Ana finds Ben and sends a friend request ​

bash
curl -s "$API/users/search?q=ben" -H "X-Client-Key: $CK" -H "Authorization: Bearer $ANA_TOKEN" | jq '.data[] | {id, username, friendshipStatus}'
# { "id": "01JC…", "username": "ben_tan", "friendshipStatus": "none" }

export BEN_ID=$(curl -s "$API/users/search?q=ben_tan" -H "X-Client-Key: $CK" -H "Authorization: Bearer $ANA_TOKEN" | jq -r '.data[0].id')

curl -s -X POST $API/friend-requests -H "X-Client-Key: $CK" -H "Authorization: Bearer $ANA_TOKEN" \
  -H 'Content-Type: application/json' -d "{\"userId\":\"$BEN_ID\"}" | jq '{id, status}'
# { "id": "01JD…", "status": "pending" }

4. Ben accepts ​

bash
REQ_ID=$(curl -s "$API/friend-requests?direction=incoming" -H "X-Client-Key: $CK" -H "Authorization: Bearer $BEN_TOKEN" | jq -r '.data[0].id')

curl -s -X POST $API/friend-requests/$REQ_ID/accept -H "X-Client-Key: $CK" -H "Authorization: Bearer $BEN_TOKEN" | jq '{user: .user.username, since}'
# { "user": "ana_souza", "since": "2026-10-22T14:05:00.120Z" }

5. Ana opens a chat and sends a message ​

bash
CONV_ID=$(curl -s -X POST $API/conversations/direct -H "X-Client-Key: $CK" -H "Authorization: Bearer $ANA_TOKEN" \
  -H 'Content-Type: application/json' -d "{\"userId\":\"$BEN_ID\"}" | jq -r .id)

curl -s -X POST $API/conversations/$CONV_ID/messages -H "X-Client-Key: $CK" -H "Authorization: Bearer $ANA_TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"clientMessageId\":\"$(uuidgen | tr A-Z a-z)\",\"type\":\"text\",\"body\":\"Hi Ben!\"}" | jq '{seq, body}'
# { "seq": 1, "body": "Hi Ben!" }

In the app, send messages over the WebSocket instead. The REST endpoint is a fallback.

6. Ben reads it ​

bash
curl -s "$API/conversations/$CONV_ID/messages" -H "X-Client-Key: $CK" -H "Authorization: Bearer $BEN_TOKEN" | jq '.data[] | {seq, body}'

curl -s -X POST $API/conversations/$CONV_ID/receipts -H "X-Client-Key: $CK" -H "Authorization: Bearer $BEN_TOKEN" \
  -H 'Content-Type: application/json' -d '{"type":"read","seq":1}'
# 204 No Content

Ana's view of the conversation now shows Ben's lastReadSeq: 1 — the message is read.

7. Watch events live ​

Open a WebSocket as Ana in one terminal (using websocat):

bash
websocat "wss://api.chatter.maragato.ca/v1/ws?clientKey=$CK&token=$ANA_TOKEN"

Send another message as Ben in a second terminal (repeat step 5 with $BEN_TOKEN). Ana's terminal prints a message.new event.

Questions? Reply to your invitation email.