Reference
Protections
Screening per kind of sender, allow and block lists, contacts, held mail and approvals for sends.
Calls go to https://address.seleya.ai/api. A refusal is {"error": {"code", "message"}} with its status; every code is in Errors.
Approval mode
PUT /v1/addresses/{a}/approvals
Called with a key or a person signed in.
Which of the address's sends wait for a person: off, unknown_recipients or everything. A key or app may make it stricter at once; lowering it waits for a person.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
Body
-
modeoff | unknown_recipients | everything required - off: the agent sends on its own. unknown_recipients: a send to anyone it has not written to before waits. everything: every send waits.
Answers
- 200
- Done
- 202
- Waits for a person, who was emailed a link
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
- 422
- A value is refused; the message says which
Fields of the 200 answer
-
addressstring -
approvalsstring
curl -X PUT https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/approvals \
-H "Authorization: Bearer $SELEYA_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "unknown_recipients"
}'import os, requests
r = requests.put(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/approvals",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
json={
"mode": "unknown_recipients"
},
)
print(r.status_code, r.json())const r = await fetch("https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/approvals", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"mode": "unknown_recipients"
}),
});
console.log(r.status, await r.json());{
"address": "desk@acme.seleya.email",
"approvals": "unknown_recipients"
}Add contacts
POST /v1/addresses/{a}/contacts
Called with a key or a person signed in.
A person saves trusted contacts directly. An agent requests human approval, because a contact bypasses unknown-recipient screening and send approval.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
Body
-
contactsarray of strings required - 1 to 100 email addresses.
Answers
- 200
- Done
- 202
- Waits for a person, who was emailed a link
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
- 422
- A value is refused; the message says which
Fields of the 200 answer
-
addedinteger
curl -X POST https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/contacts \
-H "Authorization: Bearer $SELEYA_KEY" \
-H "Content-Type: application/json" \
-d '{
"contacts": ["sam@beta.com"]
}'import os, requests
r = requests.post(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/contacts",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
json={
"contacts": ["sam@beta.com"]
},
)
print(r.status_code, r.json())const r = await fetch("https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/contacts", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"contacts": ["sam@beta.com"]
}),
});
console.log(r.status, await r.json());{
"added": 1
}Screening per class
PUT /v1/addresses/{a}/screening
Called with a key or a person signed in.
What happens to mail from each kind of sender: delivered, held or rejected. A key or app may make it stricter at once; a looser setting waits for a person.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
Answers
- 200
- Done
- 202
- Waits for a person, who was emailed a link
- 401
- No valid key, session or token
- 403
- Not allowed for this caller
- 404
- Not found, or not yours to see
- 422
- A value is refused; the message says which
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 -
approvalsoff | unknown_recipients | everything
curl -X PUT https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/screening \
-H "Authorization: Bearer $SELEYA_KEY" \
-H "Content-Type: application/json" \
-d '{
"stranger": "held",
"unverified": "rejected"
}'import os, requests
r = requests.put(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/screening",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
json={
"stranger": "held",
"unverified": "rejected"
},
)
print(r.status_code, r.json())const r = await fetch("https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/screening", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"stranger": "held",
"unverified": "rejected"
}),
});
console.log(r.status, await r.json());{
"address": "ct-c@beta.com",
"display_name": "Contract agent C",
"holder_emails": [],
"holder_person_id": null,
"id": "7f3c9a2e-0000-4000-8000-000000000033",
"owner_id": "7f3c9a2e-0000-4000-8000-000000000034",
"screening": {
"stranger": "rejected"
},
"status": "active"
}Allow and block lists
GET /v1/addresses/{a}/senders
Called with a key or a person signed in.
The address's allow and block lists.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
Answers
- 200
- Done
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
Fields of the 200 answer
-
sendersarray of objects
curl https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/senders \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.get(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/senders",
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/senders", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());{
"senders": [
{
"entry": "spam.example",
"action": "block"
}
]
}Allow or block a sender
PUT /v1/addresses/{a}/senders
Called with a key or a person signed in.
Allows or blocks a sender (an address or @domain). Blocking happens at once; allowing waits for a person when a key or app asks.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
Body
-
entrystring required - A sender's address, or @domain for everyone at it. An address beats its domain.
-
actionallow | block required - allow delivers its mail whatever its class; block drops it.
Answers
- 200
- Done
- 202
- Waits for a person, who was emailed a link
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
- 422
- A value is refused; the message says which
Fields of the 200 answer
-
entrystring -
actionstring
curl -X PUT https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/senders \
-H "Authorization: Bearer $SELEYA_KEY" \
-H "Content-Type: application/json" \
-d '{
"entry": "@beta.com",
"action": "block"
}'import os, requests
r = requests.put(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/senders",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
json={
"entry": "@beta.com",
"action": "block"
},
)
print(r.status_code, r.json())const r = await fetch("https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/senders", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"entry": "@beta.com",
"action": "block"
}),
});
console.log(r.status, await r.json());{
"entry": "spam.example",
"action": "block"
}Remove a list entry
DELETE /v1/addresses/{a}/senders/{e}
Called with a key or a person signed in.
Removes a list entry. Unblocking waits for a person when a key or app asks.
Parameters
-
astring, in path required - The address, such as desk@acme.seleya.email.
-
estring, in path required - The list entry: an address or @domain.
Answers
- 202
- Waits for a person, who was emailed a link
- 204
- Done, with no body
- 401
- No valid key, session or token
- 404
- Not found, or not yours to see
- 422
- A value is refused; the message says which
Fields of the 202 answer
-
statusawaiting_approval - awaiting_approval.
-
approvalobject - The ask: its id, kind and who decides.
curl -X DELETE https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/senders/@beta.com \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.delete(
"https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/senders/@beta.com",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
)
print(r.status_code, r.text)const r = await fetch("https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/senders/@beta.com", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status);{
"status": "awaiting_approval",
"approval": {
"id": "7f3c9a2e-0000-4000-8000-000000000001",
"kind": "unblock_sender",
"summary": "unblock spam.example",
"waits_for": "a person, who was sent a link by email"
}
}Block a held message's sender
POST /v1/deliveries/{id}/block
Called with a key or a person signed in.
Blocks a held message's sender and drops the message.
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
-
blockedstring -
deliverystring
curl -X POST https://address.seleya.ai/api/v1/deliveries/ID/block \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.post(
"https://address.seleya.ai/api/v1/deliveries/ID/block",
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/block", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());{
"blocked": "spam@beta.example",
"delivery": "7f3c9a2e-0000-4000-8000-000000000001"
}Release held mail
POST /v1/deliveries/{id}/release
Called with a key or a person signed in.
Releases held mail and makes its sender a contact. A person releases at once; a key or app's request waits for one.
Parameters
-
idstring, in path required - Its id.
Answers
- 200
- Done
- 202
- Waits for a person, who was emailed a link
- 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 - 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 -X POST https://address.seleya.ai/api/v1/deliveries/ID/release \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.post(
"https://address.seleya.ai/api/v1/deliveries/ID/release",
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/release", {
method: "POST",
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
}
}Held mail
GET /v1/held
Called with a key or a person signed in.
Mail held for a person. A key or app sees who sent it and why, never the text.
Parameters
-
addressstring, in query - One address.
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
-
heldarray of Message
curl https://address.seleya.ai/api/v1/held \
-H "Authorization: Bearer $SELEYA_KEY"import os, requests
r = requests.get(
"https://address.seleya.ai/api/v1/held",
headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
)
print(r.status_code, r.json())const r = await fetch("https://address.seleya.ai/api/v1/held", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());{
"held": []
}