SeleID

API reference

Webhooks, queue, SeleMail, routing and push API

All APIs · SDKs · Continue with SeleID (OIDC) · SeleStorage · SeleBase · Webhooks, queue, SeleMail, routing and push · SeleAI · SeleDomains search

Coming soon Version 1.0.0. Webhooks signed with HMAC-SHA256 (header seleid-signature: t=<unix>,v1=<hex> over "<t>.<body>"), a durable job queue, email sending, inbound routing and push. Auth reuses the SeleStorage key table.

Base URL

https://api.seleid.dev Base URL.

Authentication and scopes

Bearer API key. Scopes: read, write, admin.

Rate limits and quotas

Monthly queue operations and mail sends by plan are hard stops (429 quota_exceeded, allowance_exceeded). Mail overage happens only if you set an overage limit.

Endpoints

GET /v1/webhooks/endpoints

List webhook endpoints. Scope: read.

Authentication: API key, scope or role read.

curl

curl -X GET "https://api.seleid.dev/v1/webhooks/endpoints" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/webhooks/endpoints', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.get(
    "https://api.seleid.dev/v1/webhooks/endpoints",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Endpoints.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/webhooks/endpoints

Create a webhook endpoint. Scope: admin. https and public URLs only; redirects are not followed; 10 s timeout. The signing secret is returned once.

Authentication: API key, scope or role admin.

curl

curl -X POST "https://api.seleid.dev/v1/webhooks/endpoints" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/hooks/sele","events":["order.created"]}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/webhooks/endpoints', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "url": "https://example.com/hooks/sele",
    "events": [
      "order.created"
    ]
  }),
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/webhooks/endpoints",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={
        "url": "https://example.com/hooks/sele",
        "events": [
            "order.created",
        ],
    }
)
print(res.status_code, res.text)
StatusMeaning
201Created.
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
429Plan quota or rate limit reached. Hard stop, never an overage charge.

DELETE /v1/webhooks/endpoints/{id}

Delete an endpoint. Scope: admin.

Authentication: API key, scope or role admin.

ParameterInRequiredDescription
idpathyesEndpoint id.

curl

curl -X DELETE "https://api.seleid.dev/v1/webhooks/endpoints/YOUR_ID" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/webhooks/endpoints/YOUR_ID', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.delete(
    "https://api.seleid.dev/v1/webhooks/endpoints/YOUR_ID",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Deleted.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/webhooks/endpoints/{id}/rotate

Rotate the signing secret. Scope: admin.

Authentication: API key, scope or role admin.

ParameterInRequiredDescription
idpathyesEndpoint id.

curl

curl -X POST "https://api.seleid.dev/v1/webhooks/endpoints/YOUR_ID/rotate" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/webhooks/endpoints/YOUR_ID/rotate', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/webhooks/endpoints/YOUR_ID/rotate",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200New secret.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
404Not found.

POST /v1/events

Emit an event to matching endpoints. Scope: write. Deliveries are queued and retried with backoff.

Authentication: API key, scope or role write.

curl

curl -X POST "https://api.seleid.dev/v1/events" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"order.created","data":{"id":"o_1"}}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/events', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "type": "order.created",
    "data": {
      "id": "o_1"
    }
  }),
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/events",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={
        "type": "order.created",
        "data": {
            "id": "o_1",
        },
    }
)
print(res.status_code, res.text)
StatusMeaning
202Accepted.
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
429Plan quota or rate limit reached. Hard stop, never an overage charge.

GET /v1/webhooks/deliveries

Delivery log. Scope: read.

Authentication: API key, scope or role read.

ParameterInRequiredDescription
endpointquerynoFilter by endpoint id.

curl

curl -X GET "https://api.seleid.dev/v1/webhooks/deliveries" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/webhooks/deliveries', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.get(
    "https://api.seleid.dev/v1/webhooks/deliveries",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Deliveries.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/webhooks/deliveries/{id}/replay

Replay a delivery. Scope: write.

Authentication: API key, scope or role write.

ParameterInRequiredDescription
idpathyesDelivery id.

curl

curl -X POST "https://api.seleid.dev/v1/webhooks/deliveries/YOUR_ID/replay" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/webhooks/deliveries/YOUR_ID/replay', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/webhooks/deliveries/YOUR_ID/replay",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
202Queued.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
404Not found.
429Plan quota or rate limit reached. Hard stop, never an overage charge.

GET /v1/queue/dead

List exhausted jobs. Scope: admin.

Authentication: API key, scope or role admin.

curl

curl -X GET "https://api.seleid.dev/v1/queue/dead" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/queue/dead', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.get(
    "https://api.seleid.dev/v1/queue/dead",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Jobs.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/queue/dead/{id}/retry

Retry an exhausted job. Scope: admin.

Authentication: API key, scope or role admin.

ParameterInRequiredDescription
idpathyesJob id.

curl

curl -X POST "https://api.seleid.dev/v1/queue/dead/YOUR_ID/retry" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/queue/dead/YOUR_ID/retry', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/queue/dead/YOUR_ID/retry",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
202Queued.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

GET /v1/usage

Usage this month. Scope: read.

Authentication: API key, scope or role read.

curl

curl -X GET "https://api.seleid.dev/v1/usage" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/usage', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.get(
    "https://api.seleid.dev/v1/usage",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Usage.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/mail/send

Send an email. Scope: write. Suppressed recipients are skipped. Overage only with an opt-in limit.

Authentication: API key, scope or role write.

curl

curl -X POST "https://api.seleid.dev/v1/mail/send" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"hello@yourdomain.com","to":"ada@example.com","subject":"Welcome","text":"Hi Ada"}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/mail/send', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "from": "hello@yourdomain.com",
    "to": "ada@example.com",
    "subject": "Welcome",
    "text": "Hi Ada"
  }),
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/mail/send",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={
        "from": "hello@yourdomain.com",
        "to": "ada@example.com",
        "subject": "Welcome",
        "text": "Hi Ada",
    }
)
print(res.status_code, res.text)
StatusMeaning
200Result.
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
429Plan quota or rate limit reached. Hard stop, never an overage charge.
503mail_unavailable.

PUT /v1/mail/overage-limit

Set the overage limit. Scope: admin.

Authentication: API key, scope or role admin.

curl

curl -X PUT "https://api.seleid.dev/v1/mail/overage-limit" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/mail/overage-limit', {
  method: 'PUT',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({}),
});
const data = await res.json();

Python

import os, requests

res = requests.put(
    "https://api.seleid.dev/v1/mail/overage-limit",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={}
)
print(res.status_code, res.text)
StatusMeaning
200Set.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

GET /v1/mail/suppressions

List suppressed addresses. Scope: read.

Authentication: API key, scope or role read.

curl

curl -X GET "https://api.seleid.dev/v1/mail/suppressions" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/mail/suppressions', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.get(
    "https://api.seleid.dev/v1/mail/suppressions",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Addresses.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

DELETE /v1/mail/suppressions/{email}

Remove a suppression. Scope: admin.

Authentication: API key, scope or role admin.

ParameterInRequiredDescription
emailpathyesURL-encoded address.

curl

curl -X DELETE "https://api.seleid.dev/v1/mail/suppressions/YOUR_EMAIL" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/mail/suppressions/YOUR_EMAIL', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.delete(
    "https://api.seleid.dev/v1/mail/suppressions/YOUR_EMAIL",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Removed.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/mail/bounces

Report a bounce. Scope: admin. Hard bounces and complaints suppress the address.

Authentication: API key, scope or role admin.

curl

curl -X POST "https://api.seleid.dev/v1/mail/bounces" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/mail/bounces', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({}),
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/mail/bounces",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={}
)
print(res.status_code, res.text)
StatusMeaning
202Recorded.
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/routing/domains

Add an Email Routing domain. Scope: admin.

Authentication: API key, scope or role admin.

curl

curl -X POST "https://api.seleid.dev/v1/routing/domains" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/routing/domains', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({}),
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/routing/domains",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={}
)
print(res.status_code, res.text)
StatusMeaning
201Added.
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
409domain_taken.
502routing_api_error.

GET /v1/routing/rules

List routing rules. Scope: read.

Authentication: API key, scope or role read.

curl

curl -X GET "https://api.seleid.dev/v1/routing/rules" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/routing/rules', {
  method: 'GET',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.get(
    "https://api.seleid.dev/v1/routing/rules",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Rules.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/routing/rules

Add a routing rule. Scope: admin. Action types: forward (verified destination), webhook (https URL) or code.

Authentication: API key, scope or role admin.

curl

curl -X POST "https://api.seleid.dev/v1/routing/rules" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain":"yourdomain.com","local":"support","action":{"type":"forward","to":"team@example.com"}}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/routing/rules', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "domain": "yourdomain.com",
    "local": "support",
    "action": {
      "type": "forward",
      "to": "team@example.com"
    }
  }),
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/routing/rules",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={
        "domain": "yourdomain.com",
        "local": "support",
        "action": {
            "type": "forward",
            "to": "team@example.com",
        },
    }
)
print(res.status_code, res.text)
StatusMeaning
201Added.
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
409address_taken.

DELETE /v1/routing/rules/{id}

Remove a routing rule. Scope: admin.

Authentication: API key, scope or role admin.

ParameterInRequiredDescription
idpathyesRule id.

curl

curl -X DELETE "https://api.seleid.dev/v1/routing/rules/YOUR_ID" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/routing/rules/YOUR_ID', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.delete(
    "https://api.seleid.dev/v1/routing/rules/YOUR_ID",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Removed.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/push/devices

Register a device token. Scope: write.

Authentication: API key, scope or role write.

curl

curl -X POST "https://api.seleid.dev/v1/push/devices" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"userId":"u1","platform":"android","token":"DEVICE_TOKEN"}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/push/devices', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "userId": "u1",
    "platform": "android",
    "token": "DEVICE_TOKEN"
  }),
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/push/devices",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={
        "userId": "u1",
        "platform": "android",
        "token": "DEVICE_TOKEN",
    }
)
print(res.status_code, res.text)
StatusMeaning
201Registered.
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

DELETE /v1/push/devices/{id}

Unregister a device. Scope: write.

Authentication: API key, scope or role write.

ParameterInRequiredDescription
idpathyesDevice id.

curl

curl -X DELETE "https://api.seleid.dev/v1/push/devices/YOUR_ID" \
  -H "Authorization: Bearer $SELE_KEY"

TypeScript

const res = await fetch('https://api.seleid.dev/v1/push/devices/YOUR_ID', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}` },
});
const data = await res.json();

Python

import os, requests

res = requests.delete(
    "https://api.seleid.dev/v1/push/devices/YOUR_ID",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"}
)
print(res.status_code, res.text)
StatusMeaning
200Removed.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.

POST /v1/push/send

Send a push to a user. Scope: write.

Authentication: API key, scope or role write.

curl

curl -X POST "https://api.seleid.dev/v1/push/send" \
  -H "Authorization: Bearer $SELE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"userId":"u1","title":"Hello","body":"You have a message"}'

TypeScript

const res = await fetch('https://api.seleid.dev/v1/push/send', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SELE_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "userId": "u1",
    "title": "Hello",
    "body": "You have a message"
  }),
});
const data = await res.json();

Python

import os, requests

res = requests.post(
    "https://api.seleid.dev/v1/push/send",
    headers={"Authorization": f"Bearer {os.environ['SELE_KEY']}"},
    json={
        "userId": "u1",
        "title": "Hello",
        "body": "You have a message",
    }
)
print(res.status_code, res.text)
StatusMeaning
200Queued.
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
429Plan quota or rate limit reached. Hard stop, never an overage charge.

Errors

HTTPMeaning
400Invalid request.
401Missing, invalid or revoked API key.
403Key lacks the required scope, or the account is suspended.
404Not found.
413Payload too large.
429Plan quota or rate limit reached. Hard stop, never an overage charge.

The machine-readable OpenAPI 3.1 description for this API lives in the SeleID repository under docs/openapi/.

Last updated 2026-11-12Suggest an editReport a problem with this page