const credentials = Buffer.from(
`${CLIENT_ID}:${CLIENT_SECRET}`
).toString('base64');
const response = await fetch('https://api.commune.email/oauth/verify-code', {
method: 'POST',
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
request_id: 'otpreq_a1b2c3d4e5f6...',
code: '482931',
}),
});
const { agent_id, access_token, refresh_token, id_token } = await response.json();
// Store agent_id in your database as the permanent identifier
resp = httpx.post(
'https://api.commune.email/oauth/verify-code',
headers={
'Authorization': f'Basic {credentials}',
'Content-Type': 'application/json',
},
json={
'request_id': 'otpreq_a1b2c3d4e5f6...',
'code': '482931',
},
)
data = resp.json()
# Store data['agent_id'] in your database
curl -X POST https://api.commune.email/oauth/verify-code \
-H "Authorization: Basic $(echo -n 'comm_client_xxx:comm_secret_xxx' | base64)" \
-H "Content-Type: application/json" \
-d '{"request_id": "otpreq_a1b2c3d4e5f6...", "code": "482931"}'
{
"access_token": "comm_oauth_a1b2c3d4...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "comm_refresh_e5f6g7h8...",
"id_token": "eyJhbGciOiJIUzI1NiIs...",
"agent_id": "agt_4f3a9b2c1d7e8a9b",
"scope": "identity"
}
Commune OAuth
Verify Code
Verify the 6-digit code and receive the agent’s identity, access token, and refresh token. Step 2 of the sign-in flow.
POST
/
oauth
/
verify-code
const credentials = Buffer.from(
`${CLIENT_ID}:${CLIENT_SECRET}`
).toString('base64');
const response = await fetch('https://api.commune.email/oauth/verify-code', {
method: 'POST',
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
request_id: 'otpreq_a1b2c3d4e5f6...',
code: '482931',
}),
});
const { agent_id, access_token, refresh_token, id_token } = await response.json();
// Store agent_id in your database as the permanent identifier
resp = httpx.post(
'https://api.commune.email/oauth/verify-code',
headers={
'Authorization': f'Basic {credentials}',
'Content-Type': 'application/json',
},
json={
'request_id': 'otpreq_a1b2c3d4e5f6...',
'code': '482931',
},
)
data = resp.json()
# Store data['agent_id'] in your database
curl -X POST https://api.commune.email/oauth/verify-code \
-H "Authorization: Basic $(echo -n 'comm_client_xxx:comm_secret_xxx' | base64)" \
-H "Content-Type: application/json" \
-d '{"request_id": "otpreq_a1b2c3d4e5f6...", "code": "482931"}'
{
"access_token": "comm_oauth_a1b2c3d4...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "comm_refresh_e5f6g7h8...",
"id_token": "eyJhbGciOiJIUzI1NiIs...",
"agent_id": "agt_4f3a9b2c1d7e8a9b",
"scope": "identity"
}
Authenticate with HTTP Basic Auth:
Authorization: Basic base64(client_id:client_secret)const credentials = Buffer.from(
`${CLIENT_ID}:${CLIENT_SECRET}`
).toString('base64');
const response = await fetch('https://api.commune.email/oauth/verify-code', {
method: 'POST',
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
request_id: 'otpreq_a1b2c3d4e5f6...',
code: '482931',
}),
});
const { agent_id, access_token, refresh_token, id_token } = await response.json();
// Store agent_id in your database as the permanent identifier
resp = httpx.post(
'https://api.commune.email/oauth/verify-code',
headers={
'Authorization': f'Basic {credentials}',
'Content-Type': 'application/json',
},
json={
'request_id': 'otpreq_a1b2c3d4e5f6...',
'code': '482931',
},
)
data = resp.json()
# Store data['agent_id'] in your database
curl -X POST https://api.commune.email/oauth/verify-code \
-H "Authorization: Basic $(echo -n 'comm_client_xxx:comm_secret_xxx' | base64)" \
-H "Content-Type: application/json" \
-d '{"request_id": "otpreq_a1b2c3d4e5f6...", "code": "482931"}'
{
"access_token": "comm_oauth_a1b2c3d4...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "comm_refresh_e5f6g7h8...",
"id_token": "eyJhbGciOiJIUzI1NiIs...",
"agent_id": "agt_4f3a9b2c1d7e8a9b",
"scope": "identity"
}
Body
string
required
From the
POST /oauth/send-code response.string
required
The 6-digit code the agent read from their inbox.
Response
string
The agent’s permanent, unique ID. Store this in your database — it never changes. Same concept as Google’s
sub field.string
Use to call
GET /oauth/agentinfo. Expires in 1 hour.string
Use to get a new access token via
POST /oauth/token. Expires in 30 days. Single-use — each refresh gives a new one.string
Signed JWT with agent claims. Can be decoded locally without calling Commune.
number
Access token lifetime in seconds (3600 = 1 hour).
string
Always
"identity".Errors
| Code | HTTP | Description |
|---|---|---|
invalid_code | 401 | Wrong code, expired, or already used. Each code works once. |
agent_inactive | 403 | Agent account has been suspended. |
origin_not_allowed | 403 | Request domain doesn’t match your registered websiteUrl. |
Last modified on March 19, 2026
Was this page helpful?

