Address

Reference

Company

Authorise a company by its domain, give out its addresses and run its admins.

Markdown

Calls go to https://address.seleya.ai/api. A refusal is {"error": {"code", "message"}} with its status; every code is in Errors.

Claim your own company address

POST /v1/addresses/self

Called with a key or a person signed in.

A person (or their app) whose email is at an authorised company's domain claims their own address there.

Body

owner string
The company, when several are at your email's domain.
local string
The name before the @. Defaults to your email's.
display_name string
The name people see. It must say it is an 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
id string
address string
owner_id string
display_name string
status active | retired
holder_emails array of strings
holder_person_id string, or null
screening map of string
capabilities Capabilities
approvals off | unknown_recipients | everything
curl -X POST https://address.seleya.ai/api/v1/addresses/self \
  -H "Authorization: Bearer $SELEYA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "display_name": "Ada'\''s agent"
}'

Answer 201
{
  "id": "7f3c9a2e-0000-4000-8000-000000000001",
  "address": "desk@acme.seleya.email",
  "owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
  "display_name": "Desk",
  "status": "active",
  "holder_emails": [
    "ada@acme.example"
  ],
  "holder_person_id": "7f3c9a2e-0000-4000-8000-000000000003",
  "screening": {}
}

Change the holder

PUT /v1/addresses/{a}/holder

Called with a key or a person signed in.

Moves the address to another person. The address and its history stay. From a key or app it waits for the company's admins.

Parameters

a string, in path required
The address, such as desk@acme.seleya.email.

Body

email string required
The new holder's email address. They get an email saying so.

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
502
Done, but an email could not be sent
Fields of the 200 answer
id string
address string
owner_id string
display_name string
status active | retired
holder_emails array of strings
holder_person_id string, or null
screening map of string
capabilities Capabilities
approvals off | unknown_recipients | everything
curl -X PUT https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/holder \
  -H "Authorization: Bearer $SELEYA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "lee@acme.com"
}'

Answer 200
{
  "id": "7f3c9a2e-0000-4000-8000-000000000001",
  "address": "desk@acme.seleya.email",
  "owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
  "display_name": "Desk",
  "status": "active",
  "holder_emails": [
    "ada@acme.example"
  ],
  "holder_person_id": "7f3c9a2e-0000-4000-8000-000000000003",
  "screening": {}
}

Retire an address

POST /v1/addresses/{a}/retire

Called with a key or a person signed in.

Retires an address for good: it stops receiving and sending, its keys end, and its name is never given out again. From a key or app it waits for the admins.

Parameters

a string, 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
Fields of the 200 answer
id string
address string
owner_id string
display_name string
status active | retired
holder_emails array of strings
holder_person_id string, or null
screening map of string
capabilities Capabilities
approvals off | unknown_recipients | everything
curl -X POST https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/retire \
  -H "Authorization: Bearer $SELEYA_KEY"

Answer 200
{
  "address": "second@acme.seleya.email",
  "display_name": "Second agent",
  "holder_emails": [],
  "holder_person_id": null,
  "id": "7f3c9a2e-0000-4000-8000-00000000002a",
  "owner_id": "7f3c9a2e-0000-4000-8000-000000000020",
  "screening": {},
  "status": "retired"
}

Start authorising a company

POST /v1/companies

Called with a key or a person signed in.

Starts authorising a company: by a DNS record, or by the company's own mail records for agents.<domain>. The legal name and country are screened against sanctions lists.

Body

name string required
The company's legal name. It is screened against sanctions lists.
domain string required
The domain its people's email is on, not a subdomain.
country string required
Where it is registered, as a two-letter code such as ZA.
method dns | mail
dns: one text record we give you. mail: the mail records for agents.<domain>, which also prove the domain. Defaults to dns.

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
429
A limit is reached
Fields of the 201 answer
id string
name string
domain string
method dns | mail
status string
country string
records object
check object
error object
company object
created_at string
curl -X POST https://address.seleya.ai/api/v1/companies \
  -H "Authorization: Bearer $SELEYA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Acme Robotics Ltd",
  "domain": "acme.com",
  "country": "ZA",
  "method": "dns"
}'

Answer 201
{
  "check": null,
  "company": null,
  "country": "ZA",
  "created_at": "2026-10-22T00:02:08.456527+00:00",
  "domain": "beta.com",
  "error": null,
  "id": "7f3c9a2e-0000-4000-8000-000000000021",
  "method": "dns",
  "name": "Pay Co 10220001",
  "own_domain": "",
  "records": [
    {
      "name": "_beta.com",
      "type": "TXT",
      "value": "seleya-address-verify=30G_rSH4qrMhjsufRafp1550yWlpbQon"
    }
  ],
  "status": "pending",
  "subdomain": "acme.seleya.email"
}

Your authorisations

GET /v1/companies/authorisations

Called with a key or a person signed in.

The company authorisations you started, open and done.

Answers

200
Done
401
No valid key, session or token
Fields of the 200 answer
authorisations array of Authorisation
curl https://address.seleya.ai/api/v1/companies/authorisations \
  -H "Authorization: Bearer $SELEYA_KEY"

Answer 200
{
  "authorisations": []
}

One authorisation

GET /v1/companies/authorisations/{id}

Called with a key or a person signed in.

One authorisation: the records to publish, the last check, and the company once it is set up.

Parameters

id string, 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
id string
name string
domain string
method dns | mail
status string
country string
records object
check object
error object
company object
created_at string
curl https://address.seleya.ai/api/v1/companies/authorisations/ID \
  -H "Authorization: Bearer $SELEYA_KEY"

Answer 200
{
  "check": "no text record at _beta.com yet; DNS can take a few minutes",
  "company": null,
  "country": "ZA",
  "created_at": "2026-10-22T00:02:08.456527+00:00",
  "domain": "beta.com",
  "error": null,
  "id": "7f3c9a2e-0000-4000-8000-000000000021",
  "method": "dns",
  "name": "Pay Co 10220001",
  "own_domain": "",
  "records": [
    {
      "name": "_beta.com",
      "type": "TXT",
      "value": "seleya-address-verify=30G_rSH4qrMhjsufRafp1550yWlpbQon"
    }
  ],
  "status": "pending"
}

Check its proof

POST /v1/companies/authorisations/{id}/check

Called with a key or a person signed in.

Checks the proof now.

Parameters

id string, in path required
Its id.

Answers

200
Done
401
No valid key, session or token
404
Not found, or not yours to see
409
Conflicts with the current state
Fields of the 200 answer
id string
name string
domain string
method dns | mail
status string
country string
records object
check object
error object
company object
created_at string
curl -X POST https://address.seleya.ai/api/v1/companies/authorisations/ID/check \
  -H "Authorization: Bearer $SELEYA_KEY"

Answer 200
{
  "check": "no text record at _beta.com yet; DNS can take a few minutes",
  "company": null,
  "country": "ZA",
  "created_at": "2026-10-22T00:02:08.456527+00:00",
  "domain": "beta.com",
  "error": null,
  "id": "7f3c9a2e-0000-4000-8000-000000000021",
  "method": "dns",
  "name": "Pay Co 10220001",
  "own_domain": "",
  "records": [
    {
      "name": "_beta.com",
      "type": "TXT",
      "value": "seleya-address-verify=30G_rSH4qrMhjsufRafp1550yWlpbQon"
    }
  ],
  "status": "pending"
}

A company

GET /v1/companies/{o}

Called with a key or a person signed in.

A company, for its admins: its domains, status, addresses and admins.

Parameters

o string, in path required
The company's owner id.

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
owner_id string
name string
proven_domain string
mail_domain string
own_domain string
address_domains array of strings
status string
addresses integer
members array of objects
capabilities Capabilities
curl https://address.seleya.ai/api/v1/companies/OWNER_ID \
  -H "Authorization: Bearer $SELEYA_KEY"

Answer 200
{
  "owner_id": "7f3c9a2e-0000-4000-8000-000000000002",
  "name": "Acme",
  "proven_domain": "acme.example",
  "mail_domain": "acme.seleya.email",
  "own_domain": "",
  "address_domains": [
    "acme.seleya.email"
  ],
  "status": "active",
  "addresses": 1,
  "members": [
    {
      "person_id": "7f3c9a2e-0000-4000-8000-000000000003",
      "email": "ada@acme.example",
      "role": "admin"
    }
  ]
}

Add an admin

POST /v1/companies/{o}/members

Called with a key or a person signed in.

Adds an admin. It grants authority, so from a key or app it waits for the admins.

Parameters

o string, in path required
The company's owner id.

Body

email string required
The new admin's email address. They get an email saying so.

Answers

201
Made
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
502
Done, but an email could not be sent
Fields of the 202 answer
status awaiting_approval
awaiting_approval.
approval object
The ask: its id, kind and who decides.
curl -X POST https://address.seleya.ai/api/v1/companies/OWNER_ID/members \
  -H "Authorization: Bearer $SELEYA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "lee@acme.com"
}'

Answer 201
{
  "person_id": "7f3c9a2e-0000-4000-8000-000000000003",
  "email": "ada@acme.example",
  "role": "admin"
}

Remove an admin

DELETE /v1/companies/{o}/members/{p}

Called with a key or a person signed in.

Removes an admin. From a key or app it waits for the admins.

Parameters

o string, in path required
The company's owner id.
p string, in path required
The admin's person id.

Answers

202
Waits for a person, who was emailed a link
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
409
Conflicts with the current state
Fields of the 202 answer
status awaiting_approval
awaiting_approval.
approval object
The ask: its id, kind and who decides.
curl -X DELETE https://address.seleya.ai/api/v1/companies/OWNER_ID/members/PERSON_ID \
  -H "Authorization: Bearer $SELEYA_KEY"

Answer 202
{
  "status": "awaiting_approval",
  "approval": {
    "id": "7f3c9a2e-0000-4000-8000-000000000001",
    "kind": "remove_admin",
    "summary": "remove ada@acme.example as admin",
    "waits_for": "a person, who was sent a link by email"
  }
}

Docs