Reference
Addresses
Make addresses, read what they receive, and look one up in full.
Calls go to https://address.seleya.ai/api. A refusal is {"error": {"code", "message"}} with its status; every code is in Errors.
Claim an address
POST /v1/addresses
Called with a key or a person signed in.
Makes an address for an authorised company. An admin calls it with an owner key or from address.seleya.ai, or an app acting for one. The answer carries the address's first key, except for an app, whose connection gets the address instead.
Body
-
ownerstring - The company's owner id. Needed only when you run more than one company.
-
domainstring - One of the company's address domains. Defaults to its subdomain of seleya.email.
-
localstring required - The name before the @: 1 to 64 of a-z, 0-9, dot, dash and underscore.
-
display_namestring required - The name people see. It must say it is an agent, such as "Acme support agent".
-
holder_emailstring - The person accountable for the address. They get an email saying so.
-
labelstring - Names the address's first key, such as "Support agent".
Answers
- 201
- Made
- 401
- No valid key, session or token
- 403
- Not allowed for this caller
- 409
- Conflicts with the current state
- 422
- A value is refused; the message says which
Fields of the 201 answer
-
idstring -
addressstring -
owner_idstring -
display_namestring -
statusactive | retired -
holder_emailsarray of strings -
holder_person_idstring, or null -
screeningmap of string -
capabilitiesCapabilities -
approvalsoff | unknown_recipients | everything
curl -X POST https://address.seleya.ai/api/v1/addresses \
-H "Authorization: Bearer $SELEYA_KEY" \
-H "Content-Type: application/json" \
-d '{
"local": "desk",
"display_name": "Acme support agent",
"holder_email": "ada@acme.com",
"label": "Support agent"
}'import os, requests
r = requests.post(
"https://address.seleya.ai/api/v1/addresses",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
json={
"local": "desk",
"display_name": "Acme support agent",
"holder_email": "ada@acme.com",
"label": "Support agent"
},
)
print(r.status_code, r.json())const r = await fetch("https://address.seleya.ai/api/v1/addresses", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"local": "desk",
"display_name": "Acme support agent",
"holder_email": "ada@acme.com",
"label": "Support agent"
}),
});
console.log(r.status, await r.json());{
"address": "first@acme.seleya.email",
"display_name": "First agent",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000028",
"key": {
"id": "7f3c9a2e-0000-4000-8000-000000000029",
"secret": "sa_test_…"
},
"owner_id": "7f3c9a2e-0000-4000-8000-000000000020",
"screening": {},
"status": "active"
}Your addresses
GET /v1/addresses
Called with a key or a person signed in.
The addresses the caller can act for.
Answers
- 200
- Done
- 401
- No valid key, session or token
- 403
- Not allowed for this caller
Fields of the 200 answer
-
addressesarray of Address
curl https://address.seleya.ai/api/v1/addresses \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.get(
"https://address.seleya.ai/api/v1/addresses",
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", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());{
"addresses": [
{
"address": "ada@beta.com",
"display_name": "Ada's agent",
"holder_emails": [
"holder@beta.com"
],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000001",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ada@beta.com",
"display_name": "Ada's agent",
"holder_emails": [
"holder@beta.com"
],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000003",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ada@beta.com",
"display_name": "Ada's agent",
"holder_emails": [
"holder@beta.com"
],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000004",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ada@beta.com",
"display_name": "Ada's agent",
"holder_emails": [
"holder@beta.com"
],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000005",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ada@beta.com",
"display_name": "Ada's agent",
"holder_emails": [
"holder@beta.com"
],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000006",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ada@beta.com",
"display_name": "Ada's agent",
"holder_emails": [
"holder@beta.com"
],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000007",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "bob@beta.com",
"display_name": "Bob's agent",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000008",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "bob@beta.com",
"display_name": "Bob's agent",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000009",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "bob@beta.com",
"display_name": "Bob's agent",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000000a",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "bob@beta.com",
"display_name": "Bob's agent",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000000b",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "bob@beta.com",
"display_name": "Bob's agent",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000000c",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "bob@beta.com",
"display_name": "Bob's agent",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000000d",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-a@beta.com",
"display_name": "Contract agent A",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000000e",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-a@beta.com",
"display_name": "Contract agent A",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000000f",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-a@beta.com",
"display_name": "Contract agent A",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000010",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-a@beta.com",
"display_name": "Contract agent A",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000011",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-a@beta.com",
"display_name": "Contract agent A",
"holder_emails": [],
"holder_person_id": null,
"id": "ba751b6e-6435-4357-ad39-6df26a",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-a@beta.com",
"display_name": "Contract agent A",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000012",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-a@beta.com",
"display_name": "Contract agent A",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000013",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-a@beta.com",
"display_name": "Contract agent A",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000014",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-b@beta.com",
"display_name": "Contract agent B",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000015",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-b@beta.com",
"display_name": "Contract agent B",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000016",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-b@beta.com",
"display_name": "Contract agent B",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000017",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-b@beta.com",
"display_name": "Contract agent B",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000018",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-b@beta.com",
"display_name": "Contract agent B",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000019",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-b@beta.com",
"display_name": "Contract agent B",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000001a",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-b@beta.com",
"display_name": "Contract agent B",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000001b",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
},
{
"address": "ct-b@beta.com",
"display_name": "Contract agent B",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-00000000001c",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
"screening": {},
"status": "active"
}
]
}An address in full
GET /v1/addresses/{a}
Called with a key or a person signed in.
An address with its holder, lists, keys, connected apps, the approvals waiting and today's quota.
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
-
idstring -
addressstring -
owner_idstring -
display_namestring -
statusactive | retired -
holder_emailsarray of strings -
holder_person_idstring, or null -
screeningmap of string -
capabilitiesCapabilities -
approvalsstring -
holderstring, or null -
sendersarray of objects -
bindingsarray of Binding -
pending_approvalsinteger -
connectionsarray of objects -
quotaobject -
companyobject
curl https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.get(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email",
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", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());{
"address": "apps@seleya.me",
"approvals": "off",
"bindings": [],
"company": null,
"connections": [
{
"app": "Seleya Address test client",
"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"
}
],
"display_name": "Test's agent",
"holder": "apps@acme.com",
"holder_emails": [
"apps@acme.com"
],
"holder_person_id": "7f3c9a2e-0000-4000-8000-00000000001e",
"id": "d4cd2e17-2261-4177-91ae-4b",
"owner_id": "7f3c9a2e-0000-4000-8000-00000000001f",
"pending_approvals": 1,
"quota": {
"address": {
"limit": 50,
"used": 0
},
"company": {
"limit": 500,
"used": 0
}
},
"screening": {},
"senders": [
{
"action": "block",
"entry": "spam@example.com"
}
],
"status": "active"
}Read by cursor
GET /v1/addresses/{a}/messages
Called with a key or a person signed in.
Delivered messages after a sequence number, oldest first. Pass next_after back as after to read on, and no message is ever missed. Held mail never appears here.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
-
afterinteger, in query - The sequence number to read after. 0, or left out, starts at the first message.
-
limitinteger, in query - How many to answer: 1 to 100. Defaults to 50.
-
waitinteger, in query - Seconds to wait for the next message when none is there yet: 0 to 20.
Answers
- 200
- Done
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
- 422
- bad_cursor or bad_query
Fields of the 200 answer
-
messagesarray of Message -
next_afterinteger
curl https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/messages?after=0&wait=20 \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.get(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/messages?after=0&wait=20",
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/messages?after=0&wait=20", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());{
"messages": [],
"next_after": 0
}One delivery
GET /v1/deliveries/{id}
Called with a key or a person signed in.
One delivered message. Held mail is shown only to a person.
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
Fields of the 200 answer
-
idstring - The delivery's id: pass it as in_reply_to to reply.
-
seqinteger, or null - Its place in the address's stream; read after it to go on.
-
addressstring - The address that received it.
-
conversation_idstring - The thread it belongs to.
-
screeningstring - delivered, held or rejected.
-
trustTrust - The verdict on its sender.
-
messageobject - The message itself.
-
received_atstring - When it arrived.
curl https://address.seleya.ai/api/v1/deliveries/ID \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.get(
"https://address.seleya.ai/api/v1/deliveries/ID",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
)
print(r.status_code, r.json())const r = await fetch("https://address.seleya.ai/api/v1/deliveries/ID", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());{
"address": "mx-b@beta.com",
"conversation_id": "7f3c9a2e-0000-4000-8000-000000000022",
"id": "7f3c9a2e-0000-4000-8000-000000000023",
"message": {
"cc": [],
"from": "mx-a@beta.com",
"id": "7f3c9a2e-0000-4000-8000-000000000024",
"in_reply_to": "",
"message_id_header": "<010701a161094821-7f3c9a2e-0000-4000-8000-000000000025@eu-central-1.amazonses.com>",
"parts": [
{
"kind": "text",
"text": "Shall we meet on Tuesday at 10:00?"
}
],
"references": [],
"subject": "Mixed 10220035",
"to": [
"person@beta.com",
"mx-b@beta.com"
],
"transport": "mixed"
},
"received_at": "2026-10-22T00:36:00.900113+00:00",
"screening": "delivered",
"seq": 1,
"trust": {
"class": "known",
"evidence": {
"dkim": "PASS",
"dmarc": "PASS",
"dmarc_policy": "",
"spam": "PASS",
"spf": "PASS",
"transport": "native",
"virus": "PASS",
"why": "a contact of this address; sent natively by an address on the service"
},
"untrusted": false
}
}