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

POST/v1/identities

Provision a new disposable email identity with a unique inbox address.

Request body

FieldTypeRequiredDescription
labelstringYesHuman-readable label for the identity
domainstringNoCustom domain (defaults to inbox.aidenid.com)
ttl_hoursintegerNoTime-to-live in hours (default: 24)
metadataobjectNoArbitrary 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

GET/v1/identities

List all identities in the current project with optional filtering.

Query parameters

ParameterTypeDescription
statusstringFilter by status: provisioned, active, extended, squashed, expired
limitintegerMax results per page (default: 50, max: 200)
offsetintegerPagination 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

GET/v1/identities/{identity_id}

Retrieve a specific identity by its ID.

Extend identity

POST/v1/identities/{identity_id}/extend

Extend the TTL of an active or provisioned identity. The identity must not be squashed or expired.

Request body

FieldTypeRequiredDescription
additional_hoursintegerYesNumber 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

POST/v1/identities/{identity_id}/squash

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

GET/v1/identities/{identity_id}/events

List inbound events for an identity. Events include email arrivals, extraction results, and lifecycle transitions.

Get latest event

GET/v1/identities/{identity_id}/events/latest

Get the most recent event for an identity.

Get latest extraction

GET/v1/identities/{identity_id}/extractions/latest

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
}
Polling vs. webhooks

While you can poll this endpoint, we recommend setting up webhooks to receive extraction.completed events in real time.

Create child identity

POST/v1/identities/{identity_id}/children

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

FieldTypeRequiredDescription
labelstringYesLabel for the child identity
ttl_hoursintegerNoTTL for the child (default: parent TTL)

Revoke children

DELETE/v1/identities/{identity_id}/children

Squash all child identities linked to a parent.

Get identity lineage

GET/v1/identities/{identity_id}/lineage

Retrieve the full lineage tree for an identity, including parent and all children.

Bulk create

POST/v1/identities/bulk

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

POST/v1/identities/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

CodeStatusDescription
identity_not_found404Identity does not exist in this project
identity_already_squashed409Cannot modify a squashed identity
identity_expired409Cannot extend or use an expired identity
quota_exceeded403Active identity limit reached for your plan
missing_idempotency_key400Mutation request missing Idempotency-Key header