Identities API
Identities are the core resource in AIdenID. Each identity represents a disposable email inbox that can receive mail and extract authentication codes.
Create identity
Provision a new disposable email identity with a unique inbox address.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Human-readable label for the identity |
domain | string | No | Custom domain (defaults to inbox.aidenid.com) |
ttl_hours | integer | No | Time-to-live in hours (default: 24) |
metadata | object | No | Arbitrary key-value pairs for your own tracking |
curl -X POST https://api.aidenid.com/v1/identities \
-H "Authorization: Bearer aid_your_api_key" \
-H "X-Org-Id: org_abc123" \
-H "X-Project-Id: proj_def456" \
-H "Idempotency-Key: <GENERATED_UNIQUE_KEY>" \
-H "Content-Type: application/json" \
-d '{
"label": "signup-test",
"ttl_hours": 48,
"metadata": { "agent": "onboarding-bot" }
}'Response
{
"id": "ident_a1b2c3d4e5",
"email": "a1b2c3d4e5@inbox.aidenid.com",
"label": "signup-test",
"status": "provisioned",
"created_at": "2026-04-04T10:00:00Z",
"expires_at": "2026-04-06T10:00:00Z",
"metadata": { "agent": "onboarding-bot" }
}List identities
List all identities in the current project with optional filtering.
Query parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: provisioned, active, extended, squashed, expired |
limit | integer | Max results per page (default: 50, max: 200) |
offset | integer | Pagination offset |
curl "https://api.aidenid.com/v1/identities?status=active&limit=10" \
-H "Authorization: Bearer aid_your_api_key" \
-H "X-Org-Id: org_abc123" \
-H "X-Project-Id: proj_def456"Get identity
Retrieve a specific identity by its ID.
Extend identity
Extend the TTL of an active or provisioned identity. The identity must not be squashed or expired.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
additional_hours | integer | Yes | Number of hours to add to the current TTL |
curl -X POST https://api.aidenid.com/v1/identities/ident_a1b2c3d4e5/extend \
-H "Authorization: Bearer aid_your_api_key" \
-H "X-Org-Id: org_abc123" \
-H "X-Project-Id: proj_def456" \
-H "Idempotency-Key: <GENERATED_UNIQUE_KEY>" \
-H "Content-Type: application/json" \
-d '{ "additional_hours": 48 }'Squash identity
Immediately revoke an identity. This disables the inbox, halts extraction, and transitions the identity to squashed status. This action is irreversible.
curl -X POST https://api.aidenid.com/v1/identities/ident_a1b2c3d4e5/squash \
-H "Authorization: Bearer aid_your_api_key" \
-H "X-Org-Id: org_abc123" \
-H "X-Project-Id: proj_def456" \
-H "Idempotency-Key: <GENERATED_UNIQUE_KEY>"List identity events
List inbound events for an identity. Events include email arrivals, extraction results, and lifecycle transitions.
Get latest event
Get the most recent event for an identity.
Get latest extraction
Get the most recent extraction result. Returns the extracted value (OTP code, magic link URL, etc.) along with extraction type and confidence score.
Response
{
"id": "ext_m1n2o3",
"identity_id": "ident_a1b2c3d4e5",
"type": "otp",
"has_secret": true,
"redacted_value": "***",
"source_event_id": "evt_x1y2z3",
"extracted_at": "2026-04-04T10:05:02Z",
"confidence": 0.99
}While you can poll this endpoint, we recommend setting up webhooks to receive extraction.completed events in real time.
Create child identity
Create a subordinate identity linked to a parent. Useful for multi-step flows where a secondary email is needed (e.g., recovery email during signup).
Request body
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Label for the child identity |
ttl_hours | integer | No | TTL for the child (default: parent TTL) |
Revoke children
Squash all child identities linked to a parent.
Get identity lineage
Retrieve the full lineage tree for an identity, including parent and all children.
Bulk create
Create multiple identities in a single request. The batch size limit depends on your plan (5 for Starter, up to 200 for Enterprise).
curl -X POST https://api.aidenid.com/v1/identities/bulk \
-H "Authorization: Bearer aid_your_api_key" \
-H "X-Org-Id: org_abc123" \
-H "X-Project-Id: proj_def456" \
-H "Idempotency-Key: <GENERATED_UNIQUE_KEY>" \
-H "Content-Type: application/json" \
-d '{
"identities": [
{ "label": "test-1", "ttl_hours": 24 },
{ "label": "test-2", "ttl_hours": 24 },
{ "label": "test-3", "ttl_hours": 24 }
]
}'Bulk squash
Squash multiple identities in a single request.
curl -X POST https://api.aidenid.com/v1/identities/bulk-squash \
-H "Authorization: Bearer aid_your_api_key" \
-H "X-Org-Id: org_abc123" \
-H "X-Project-Id: proj_def456" \
-H "Idempotency-Key: <GENERATED_UNIQUE_KEY>" \
-H "Content-Type: application/json" \
-d '{
"identity_ids": ["ident_a1b2c3d4e5", "ident_f6g7h8i9j0"]
}'Python example
import requests
API = "https://api.aidenid.com"
HEADERS = {
"Authorization": "Bearer aid_your_api_key",
"X-Org-Id": "org_abc123",
"X-Project-Id": "proj_def456",
"Content-Type": "application/json",
}
# Create identity
identity = requests.post(
f"{API}/v1/identities",
headers={**HEADERS, "Idempotency-Key": "py-create-001"},
json={"label": "signup-test", "ttl_hours": 48},
).json()
print(f"Created identity: {identity['id']}")
# List active identities
active = requests.get(
f"{API}/v1/identities",
headers=HEADERS,
params={"status": "active", "limit": 10},
).json()
# Extend identity
requests.post(
f"{API}/v1/identities/{identity['id']}/extend",
headers={**HEADERS, "Idempotency-Key": "py-extend-001"},
json={"additional_hours": 24},
)
# Get latest extraction
extraction = requests.get(
f"{API}/v1/identities/{identity['id']}/extractions/latest",
headers=HEADERS,
)
if extraction.status_code == 200:
print(f"Extraction ready: {extraction.json()['type']}")
# Squash when done
requests.post(
f"{API}/v1/identities/{identity['id']}/squash",
headers={**HEADERS, "Idempotency-Key": "py-squash-001"},
)TypeScript example
const API = "https://api.aidenid.com";
const headers = {
Authorization: "Bearer aid_your_api_key",
"X-Org-Id": "org_abc123",
"X-Project-Id": "proj_def456",
"Content-Type": "application/json",
};
const fetchWithTimeout = async (url: string, init: RequestInit = {}, timeoutMs = 10_000) => {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
try {
return await fetch(url, { ...init, signal: controller.signal });
} finally {
clearTimeout(timeout);
}
};
// Create identity
const identity = await fetchWithTimeout(`${API}/v1/identities`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": "ts-create-001" },
body: JSON.stringify({ label: "signup-test", ttl_hours: 48 }),
}).then((r) => r.json());
console.log("Created identity:", identity.id);
// List active identities
const active = await fetchWithTimeout(
`${API}/v1/identities?status=active&limit=10`,
{ headers }
).then((r) => r.json());
// Extend identity
await fetchWithTimeout(`${API}/v1/identities/${identity.id}/extend`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": "ts-extend-001" },
body: JSON.stringify({ additional_hours: 24 }),
});
// Get latest extraction
const extResp = await fetchWithTimeout(
`${API}/v1/identities/${identity.id}/extractions/latest`,
{ headers }
);
if (extResp.ok) {
const extraction = await extResp.json();
console.log("Extraction ready:", extraction.type);
}
// Squash when done
await fetchWithTimeout(`${API}/v1/identities/${identity.id}/squash`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": "ts-squash-001" },
});Error codes
| Code | Status | Description |
|---|---|---|
identity_not_found | 404 | Identity does not exist in this project |
identity_already_squashed | 409 | Cannot modify a squashed identity |
identity_expired | 409 | Cannot extend or use an expired identity |
quota_exceeded | 403 | Active identity limit reached for your plan |
missing_idempotency_key | 400 | Mutation request missing Idempotency-Key header |