Requests & responses
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
Requests & responses
Content type
Request and response bodies are JSON. Send Content-Type: application/json on any request with a body. The wire is snake_case and the SDKs mirror it exactly — they type the API rather than inventing a second dialect.
curl -X PATCH https://api.atlas.dev/v1/users/user_2a \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"first_name":"Ada","public_metadata":{"plan":"pro"}}'Object shapes
Most resources carry an object discriminator and a string id:
{
"object": "user",
"id": "user_2a…",
"first_name": "Ada",
"last_name": null,
"public_metadata": { "plan": "pro" },
"mfa_enabled": false,
"banned": false,
"created_at": 1757600000000,
"updated_at": 1757600000000
}Ids are opaque. Prefixes (
user_,org_,sess_,role_,perm_) are a readability aid, not a contract to parse.Timestamps are epoch milliseconds (integers), or
nullwhere a value has never been set (e.g.last_sign_in_at).Nullable fields are explicit — a field is present as
nullrather than omitted.
Metadata bags
Users and organizations carry free-form JSON metadata in up to three bags:
Bag | Visible to the frontend? | Writable from the frontend? |
|---|---|---|
| Yes (in the session/user object) | No — backend only |
| No — never returned by read routes | Backend only |
| Yes | Yes (the user can set it) |
PATCH merges the bag you send; PUT …/metadata replaces the named bags wholesale.
Mutations & deletions
POSTcreates,PATCHpartially updates,PUTreplaces,DELETEremoves.Deletes return a minimal acknowledgement:
{ "object": "user", "id": "user_2a…", "deleted": true }.Some revocations return a small custom shape (e.g.
{ "object": "session", "id": "…", "status": "revoked" }).
Reading raw formats
A few routes return non-JSON when asked (e.g. SAML SP metadata XML is carried inside a JSON envelope with a metadata_xml string). The SDKs expose these as typed helpers.