Reference
Apps
Apps such as ChatGPT and Claude connect by MCP and OAuth 2.1, and act as the person's agent.
Calls go to https://address.seleya.ai/api. A refusal is {"error": {"code", "message"}} with its status; every code is in Errors.
Authorization server metadata
GET /.well-known/oauth-authorization-server
Called with .
RFC 8414: metadata documents only (no dynamic registration), PKCE S256, iss on responses.
Answers
- 200
- Done
Protected resource metadata
GET /.well-known/oauth-protected-resource
Called with .
RFC 9728, for the MCP server.
Answers
- 200
- Done
Protected resource metadata (path form)
GET /.well-known/oauth-protected-resource/mcp
Called with .
The same metadata, at the path form RFC 9728 names for the MCP server.
Answers
- 200
- Done
The MCP server
POST /mcp
Called with an app.
The MCP server, at https://address.seleya.ai/mcp. It speaks MCP 2026-07-28 and answers clients that start with initialize, over Streamable HTTP without sessions. Its tools are this API's calls, made as the app; MCP Events arrive by webhook.
Answers
- 200
- Done
- 400
- The request is malformed
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
Start an app's sign-in
GET /oauth/authorize
Called with .
Checks the app's Client ID Metadata Document and redirect, then sends the person to the consent page.
Parameters
-
client_idstring, in query - The app's metadata document URL
-
redirect_uristring, in query - Where to send the person back: one of the app's metadata document's redirect URIs.
-
response_typestring, in query - code
-
code_challengestring, in query - The PKCE challenge, base64url SHA-256 of the verifier.
-
code_challenge_methodstring, in query - S256
-
resourcestring, in query - The MCP URL
-
statestring, in query - The app's own value, returned unchanged.
-
scopestring, in query - agent, or left out.
Answers
- 302
- Redirect
Revoke
POST /oauth/revoke
Called with .
RFC 7009: ends the token's connection; always 200.
Answers
- 200
- Done
Tokens
POST /oauth/token
Called with .
authorization_code (with the PKCE verifier) or refresh_token; refresh tokens rotate, and a reused one ends the connection.
Answers
- 200
- Done
- 400
- The request is malformed
Fields of the 200 answer
-
access_tokenstring -
token_typeBearer -
expires_ininteger -
refresh_tokenstring -
scopestring
Apps using an address
GET /v1/addresses/{a}/connections
Called with a key or a person signed in.
The apps using an address, for its holder or the company's admins.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
Answers
- 200
- Done
- 401
- No valid key, session or token
- 403
- Not allowed for this caller
- 404
- Not found, or not yours to see
Fields of the 200 answer
-
connectionsarray of Connection
curl https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/connections \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.get(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/connections",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
)
print(r.status_code, r.json())const r = await fetch("https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/connections", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());{
"connections": []
}Remove an app from an address
DELETE /v1/addresses/{a}/connections/{id}
Called by address.seleya.ai, signed in.
Stops an app using this address. A person only.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
-
idstring, in path required - Its id.
Answers
- 204
- Done, with no body
- 401
- No valid key, session or token
- 403
- Not allowed for this caller
- 404
- Not found, or not yours to see
Consent: what the app asks
GET /v1/connect/{id}
Called by address.seleya.ai, signed in.
What an app asks, for the consent page and the person signed in.
Parameters
-
idstring, in path required - Its id.
Answers
- 200
- Done
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
{
"addresses": [
{
"address": "apps@seleya.me",
"display_name": "Test's agent"
}
],
"app": {
"client_id": "https://juiw7rjojt3cahaammkuzf3di40ycqbj.lambda-url.eu-central-1.on.aws/client/main.json",
"name": "Seleya Address test client",
"own_machine": true,
"returns_to": "127.0.0.1"
},
"you": "apps@acme.com"
}Consent: allow or deny
POST /v1/connect/{id}
Called by address.seleya.ai, signed in.
The person allows or refuses the app. Answers the address to return to the app.
Parameters
-
idstring, in path required - Its id.
Body
-
decisionallow | deny required - allow or deny.
-
addressesarray of strings - The addresses the app may use. It can make more for you later.
Answers
- 200
- Done
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
- 409
- Conflicts with the current state
- 422
- A value is refused; the message says which
Fields of the 200 answer
-
redirectstring
{
"redirect": "http://127.0.0.1:53117/callback?code=sac__olcfkN3yJ4_XQY05rLqoucgQLSFC6vXCoPKV718YdY&state=st-10220039&iss=https%3A%2F%2Faddress.seleya.ai"
}Apps acting for you
GET /v1/connections
Called by address.seleya.ai, signed in.
The apps acting for you, with their addresses and when each was last used.
Answers
- 200
- Done
- 401
- No valid key, session or token
Fields of the 200 answer
-
connectionsarray of Connection
{
"connections": [
{
"addresses": [
"apps@seleya.me"
],
"app": "Seleya Address test client",
"client_id": "https://juiw7rjojt3cahaammkuzf3di40ycqbj.lambda-url.eu-central-1.on.aws/client/main.json",
"id": "7f3c9a2e-0000-4000-8000-00000000001d",
"last_used_at": "2026-10-22T00:40:34.644228+00:00",
"returns_to": "127.0.0.1",
"since": "2026-10-22T00:40:33.739498+00:00"
}
]
}Disconnect from the emailed link
POST /v1/connections/by-link
Called by address.seleya.ai, signed in.
Disconnects an app from the link in the new-connection email.
Body
-
tokenstring required - The token from the emailed link's fragment.
Answers
- 200
- Done
- 404
- Not found, or not yours to see
Fields of the 200 answer
-
disconnectedstring
Disconnect an app
DELETE /v1/connections/{id}
Called by address.seleya.ai, signed in.
Disconnects an app at once. The off switch never depends on the app.
Parameters
-
idstring, in path required - Its id.
Answers
- 204
- Done, with no body
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see