{"openapi":"3.1.0","info":{"title":"domani.run API","version":"1.0.0","description":"Domain infrastructure for AI agents. One API to search, register, and connect domain names.\n\n## Authentication\n\nAll authenticated endpoints require a Bearer token:\n\n```\nAuthorization: Bearer domani_sk_xxx\n```\n\nGet your API key by registering:\n\n```bash\ncurl -X POST https://domani.run/api/auth/register \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"you@example.com\"}'\n```\n\n## Rate Limits\n\nEvery response includes `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers. When rate limited (HTTP 429), check the `Retry-After` header for seconds to wait.\n\n## Error Handling\n\nAll errors return a consistent JSON envelope with `error`, `code`, `hint`, and `documentation_url` fields. Use the `code` field for programmatic handling and the `hint` field for recovery guidance.\n\n## MCP Server\n\nA real-time MCP (Model Context Protocol) server is available at `POST /mcp` using Streamable HTTP transport. Connect any MCP-compatible agent (Claude Code, Cursor, etc.) with your Bearer token for typed tool access (search, buy, DNS, etc.).\n\n## Pagination\n\nThe `GET /api/tlds` endpoint supports `limit` and `offset` query parameters. When paginated, the response includes a `Link` header with `rel=\"next\"` for the next page.","contact":{"name":"domani.run","url":"https://domani.run"}},"servers":[{"url":"https://domani.run","description":"Production"}],"externalDocs":{"description":"Interactive API Reference","url":"https://domani.run/docs"},"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"domani_sk_xxx","description":"API key obtained from POST /api/auth/register. Include as: `Authorization: Bearer domani_sk_xxx`. Keys use the prefix `domani_sk_` followed by 32 random characters."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Machine-readable error code","enum":["MISSING_API_KEY","INVALID_API_KEY","EXPIRED_API_KEY","MISSING_PARAMETER","INVALID_DOMAIN","PAYMENT_REQUIRED","DOMAIN_UNAVAILABLE","RATE_LIMIT_EXCEEDED","USER_EXISTS","NOT_FOUND","UNKNOWN_PROVIDER","UNKNOWN_METHOD","TARGET_REQUIRED","INVALID_PARAMETER","CONTACT_REQUIRED","INVALID_CONTACT","INSUFFICIENT_SCOPE","SCOPE_ESCALATION","DOMAIN_EXISTS","DOMAIN_NOT_ACTIVE","UNSUPPORTED_TLD","NOT_AVAILABLE","ALREADY_REGISTERED","TRANSFER_NOT_ELIGIBLE","ALREADY_LISTED","LISTING_SOLD","SELF_PURCHASE","DESCRIPTION_TOO_LONG","DEAL_NOT_FOUND","INVALID_DEAL_STATE","EPP_ATTEMPTS_EXCEEDED","ACTIVE_DEAL_EXISTS","AGENT_IDENTITY_NOT_FOUND","AGENT_IDENTITY_ESCALATION","CREDENTIAL_REVOKE_FAILED"]},"hint":{"type":"string","description":"Actionable recovery guidance for the caller"},"fix_command":{"type":"string","description":"CLI command to resolve the error (e.g. 'domani login', 'domani billing'). Present in CLI --json output."},"documentation_url":{"type":"string","format":"uri","description":"Link to relevant documentation"},"setup_url":{"type":"string","format":"uri","description":"URL to resolve the issue (e.g. add payment method)"},"fix_url":{"type":"string","format":"uri","description":"URL to resolve the issue (alias for setup_url in CLI --json output)"},"retry_after":{"type":"integer","description":"Seconds until retry is allowed (present on 429 responses)"}},"required":["error","code","documentation_url"],"example":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"SearchResult":{"type":"object","properties":{"available":{"type":"boolean","description":"Whether the domain is available for registration"},"domain":{"type":"string","example":"example.com","description":"Full domain name including TLD"},"price":{"type":"number","example":10.88,"description":"Registration price in the specified currency"},"currency":{"type":"string","example":"USD","description":"ISO 4217 currency code (always USD)"},"error":{"type":"boolean","description":"True if RDAP lookup failed (availability unknown)"},"for_sale":{"type":"object","description":"Present when the domain is listed for sale (either on Domani marketplace or detected on an external aftermarket)","properties":{"price":{"type":"number","example":5000,"description":"Listed sale price in USD"},"currency":{"type":"string","example":"USD","description":"Price currency (always USD)"},"source":{"type":"string","example":"domani","description":"Where the listing originates: 'domani' for Domani marketplace, or aftermarket name (e.g. 'Sedo', 'Afternic')"},"buyable":{"type":"boolean","example":true,"description":"Whether the domain can be purchased directly via the Domani API. true for Domani listings, false for external aftermarket"},"url":{"type":"string","example":"https://sedo.com/search/details/?domain=example.com","description":"Direct link to external aftermarket listing (only present for external sources)"},"description":{"type":"string","description":"Listing description (Domani marketplace listings only)"}},"required":["price","currency","source","buyable"]}},"required":["available","domain","price","currency"]},"TldInfo":{"type":"object","properties":{"tld":{"type":"string","example":"com","description":"Top-level domain without dot prefix"},"registration":{"type":"number","example":10.88,"description":"First-year registration price in USD"},"renewal":{"type":"number","example":13.08,"description":"Annual renewal price in USD"},"transfer":{"type":"number","example":13.08,"description":"Transfer price in USD"}},"required":["tld","registration","renewal","transfer"]},"DnsRecord":{"type":"object","properties":{"type":{"type":"string","enum":["A","AAAA","CNAME","MX","TXT","NS","SRV","CAA","TLSA"],"description":"DNS record type. TLSA publishes a DANE record; its value is the rdata 'usage selector matching-type hex-data'."},"name":{"type":"string","example":"@","description":"Record name (@ for root, or subdomain, e.g. _443._tcp for TLSA)"},"value":{"type":"string","example":"76.76.21.21","description":"Record value (IP address, hostname, or TLSA rdata like '3 1 1 abc123...')"},"ttl":{"type":"integer","example":3600,"description":"Time to live in seconds"},"priority":{"type":"integer","description":"Priority value (required for MX records)"}},"required":["type","name","value","ttl"]},"DsRecord":{"type":"object","description":"A DNSSEC delegation-signer (DS) record published at the registry.","properties":{"keyTag":{"type":"string","example":"12345","description":"Key Tag identifying the DNSKEY"},"algorithm":{"type":"string","example":"13","description":"DNSSEC algorithm number (e.g. 13 = ECDSAP256SHA256, 8 = RSASHA256)"},"digestType":{"type":"string","example":"2","description":"Digest type number (e.g. 2 = SHA-256)"},"digest":{"type":"string","example":"A1B2C3...","description":"Hex digest of the DNSKEY"}},"required":["keyTag","algorithm","digestType","digest"]},"AgentIdentity":{"type":"object","description":"A free agent identity served at <slug>.domani.run.","properties":{"id":{"type":"string","description":"Stable identity id used to bind scoped API tokens"},"slug":{"type":"string","example":"myagent"},"url":{"type":"string","example":"https://myagent.domani.run","description":"The identity subdomain (canonical)"},"page_url":{"type":"string","description":"Path fallback that always works"},"name":{"type":"string","nullable":true},"bio":{"type":"string","nullable":true},"emoji":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"links":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"url":{"type":"string"}}}},"views":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}},"required":["id","slug","url","page_url","name","bio","emoji","email","links","views","created_at"]},"DomainRecord":{"type":"object","properties":{"domain":{"type":"string","example":"mysite.com"},"status":{"type":"string","enum":["active","expired","pending"],"description":"Current registration status"},"autoRenew":{"type":"boolean","description":"Whether auto-renew is enabled"},"purchasedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"emailEnabled":{"type":"boolean","description":"Whether email is set up for this domain"},"emailVerified":{"type":"boolean","description":"Whether email DNS records have been verified"},"emailVerifiedAt":{"type":"string","format":"date-time","nullable":true,"description":"When email DNS was verified (null if not yet verified)"},"mailboxCount":{"type":"integer","description":"Number of mailboxes configured for this domain"}},"required":["domain","status","autoRenew","purchasedAt","expiresAt","emailEnabled","emailVerified","mailboxCount"]},"MailRule":{"type":"object","description":"An inbound filtering rule for a mailbox","properties":{"id":{"type":"string"},"priority":{"type":"integer","description":"Lower runs first"},"match_field":{"type":"string","enum":["from","to","subject","body"]},"match_op":{"type":"string","enum":["contains","equals","regex"]},"match_value":{"type":"string"},"action":{"type":"string","enum":["drop","mark_read","forward","webhook_only","label"]},"action_arg":{"type":"string","nullable":true},"enabled":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"WorkspaceSummary":{"type":"object","description":"A personal or shared workspace visible to the current principal.","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"]},"personal":{"type":"boolean"},"member_count":{"type":"integer"},"mailbox_count":{"type":"integer"},"plans":{"type":"array","items":{"type":"object","properties":{"product":{"type":"string"},"plan":{"type":"string"},"status":{"type":"string"}},"required":["product","plan","status"]}},"created_at":{"type":"string","format":"date-time"}},"required":["id","name","role","personal","member_count","mailbox_count","plans","created_at"]},"WorkspaceDetail":{"type":"object","description":"Workspace membership, mailbox access and pending invitation state.","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"]},"personal":{"type":"boolean"},"members":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["owner","admin","member"]},"joined_at":{"type":"string","format":"date-time"},"mailbox_grants":{"type":"array","items":{"type":"object","properties":{"mailbox_id":{"type":"string"},"address":{"type":"string","format":"email"},"role":{"type":"string","enum":["viewer","responder","manager"]}}}}}}},"invitations":{"type":"array","description":"Visible only to workspace owners and admins.","items":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["admin","member"]},"expires_at":{"type":"string","format":"date-time"}}}},"mailboxes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"string","format":"email"},"name":{"type":"string","nullable":true}}}},"ownership":{"type":"object","properties":{"owner_membership_id":{"type":"string","nullable":true},"pending_transfer":{"nullable":true,"type":"object","properties":{"id":{"type":"string"},"to_email":{"type":"string","format":"email"},"expires_at":{"type":"string","format":"date-time"}},"required":["id","to_email","expires_at"]}},"required":["owner_membership_id","pending_transfer"]}},"required":["id","name","role","personal","members","invitations","mailboxes","ownership"]},"ConversationState":{"type":"object","description":"Durable shared inbox state for an email thread.","properties":{"id":{"type":"string"},"mailbox_id":{"type":"string"},"thread_key":{"type":"string"},"subject":{"type":"string","nullable":true},"status":{"type":"string","enum":["open","waiting","closed"]},"assignee":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["member","token","agent"]},"id":{"type":"string"},"label":{"type":"string"}}},"version":{"type":"integer"},"note_count":{"type":"integer"},"assigned_to_me":{"type":"boolean"},"last_activity_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","mailbox_id","thread_key","status","version","note_count","last_activity_at","created_at","updated_at"]},"ConversationNote":{"type":"object","description":"Internal note visible to workspace collaborators and never included in outbound email.","properties":{"id":{"type":"string"},"author":{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"},"label":{"type":"string"}},"required":["type","id","label"]},"body":{"type":"string"},"mentions":{"type":"array","items":{"type":"object","additionalProperties":true}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","author","body","mentions","created_at","updated_at"]},"MailActivity":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"actor":{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"},"label":{"type":"string"}},"required":["type","id","label"]},"metadata":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"}},"required":["id","type","actor","metadata","created_at"]},"Backorder":{"type":"object","description":"A watch on a taken domain that auto-registers it when it drops","properties":{"id":{"type":"string"},"domain":{"type":"string","example":"taken.com"},"status":{"type":"string","enum":["watching","caught","failed","cancelled","expired"]},"payment_method":{"type":"string","enum":["card","balance"]},"max_price":{"type":"number","description":"Max USD you'll pay to catch it"},"currency":{"type":"string","example":"USD"},"domain_expires":{"type":"string","format":"date-time","nullable":true,"description":"Current registration's expiry (informational)"},"last_checked":{"type":"string","format":"date-time","nullable":true},"attempts":{"type":"integer","description":"Number of availability checks performed"},"caught_at":{"type":"string","format":"date-time","nullable":true},"registered_domain_id":{"type":"string","nullable":true,"description":"ID of the Domain created when caught"},"failure_reason":{"type":"string","nullable":true},"expires_at":{"type":"string","format":"date-time","description":"When the watch window ends"},"created_at":{"type":"string","format":"date-time"}}},"DealInvoice":{"type":"object","description":"A role-aware receipt (buyer) or statement (seller) for a marketplace deal","properties":{"deal_id":{"type":"string"},"domain":{"type":"string","example":"example.com"},"date":{"type":"string","format":"date-time"},"status":{"type":"string"},"your_role":{"type":"string","enum":["buyer","seller"]},"currency":{"type":"string","example":"USD"},"line_items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string"},"amount":{"type":"number","description":"USD; negative for deductions like commission"}}}},"total":{"type":"number","description":"Buyer: amount paid. Seller: net payout after commission."},"commission_rate":{"type":"number","description":"Platform commission percent"},"commission_amount":{"type":"number","description":"Platform commission in USD"},"payment_method":{"type":"string","description":"Buyer only"},"payout_method":{"type":"string","enum":["bank","balance"],"description":"Seller only"},"payout_status":{"type":"string","enum":["paid","credited","pending"],"description":"Seller only"}}},"BrokerRequest":{"type":"object","description":"A request to acquire a specific taken domain (autonomous broker)","properties":{"id":{"type":"string"},"domain":{"type":"string","example":"dream.com"},"status":{"type":"string","enum":["sourcing","contacted","negotiating","agreed","completed","no_contact","declined","expired","cancelled"]},"max_budget":{"type":"number","nullable":true,"description":"Your ceiling in USD"},"contacted":{"type":"boolean","description":"Whether the owner has been reached"},"negotiation_id":{"type":"string","nullable":true,"description":"Set once the owner engages and a negotiation opens"},"failure_reason":{"type":"string","nullable":true},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"Negotiation":{"type":"object","description":"An anonymous, threaded price negotiation over a listed domain","properties":{"id":{"type":"string"},"domain":{"type":"string","example":"example.com"},"status":{"type":"string","enum":["open","agreed","completed","declined","expired","cancelled"]},"your_role":{"type":"string","enum":["buyer","seller"]},"your_turn":{"type":"boolean","description":"True when it's your move to respond"},"current_offer":{"type":"number","description":"Latest amount on the table (USD)"},"agreed_price":{"type":"number","nullable":true,"description":"Set once the price is agreed"},"list_price":{"type":"number","description":"The listing's asking price (USD)"},"expires_at":{"type":"string","format":"date-time"},"deal_id":{"type":"string","nullable":true,"description":"Set once finalized into a deal"},"created_at":{"type":"string","format":"date-time"},"offers":{"type":"array","description":"The negotiation thread, oldest first","items":{"type":"object","properties":{"from":{"type":"string","enum":["you","counterparty"]},"kind":{"type":"string","enum":["offer","counter","accept","decline"]},"amount":{"type":"number","nullable":true},"message":{"type":"string","nullable":true},"at":{"type":"string","format":"date-time"}}}}}},"DomainDetail":{"type":"object","description":"Detailed domain information","properties":{"domain":{"type":"string","example":"mysite.com"},"status":{"type":"string","enum":["active","expired","pending"]},"auto_renew":{"type":"boolean","description":"Whether auto-renew is enabled"},"purchased_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"days_until_expiry":{"type":"integer","description":"Days until domain expiry"},"payment_method":{"type":"string","enum":["card","x402","crypto"],"description":"How the domain was paid for"},"payment_tx":{"type":"string","nullable":true,"description":"On-chain tx hash (USDC payments)"},"registrar_status":{"type":"string","enum":["connected","unavailable","external"],"description":"Whether live registrar data was refreshed or is managed externally"},"registrar_checked_at":{"type":"string","format":"date-time","description":"When the registrar refresh was attempted"},"registrar":{"type":"object","nullable":true,"description":"Domain registration details (null if unavailable)","properties":{"security_lock":{"type":"boolean","description":"Whether the domain is locked against transfers"},"whois_privacy":{"type":"boolean","description":"Whether WHOIS privacy is enabled"},"auto_renew":{"type":"boolean","description":"Auto-renew status"},"create_date":{"type":"string","description":"Domain creation date"},"expire_date":{"type":"string","description":"Domain expiration date"}}}},"required":["domain","status","auto_renew","purchased_at","expires_at","days_until_expiry","payment_method","registrar_status","registrar_checked_at"]},"TokenInfo":{"type":"object","properties":{"id":{"type":"string","description":"Unique token identifier (use this for DELETE)"},"name":{"type":"string","example":"CLI","description":"Human-readable token label"},"key":{"type":"string","example":"domani_sk_...wxyz","description":"Masked API key (full key shown only on creation)"},"lastUsed":{"type":"string","format":"date-time","nullable":true,"description":"Last time this token was used"},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"When this token expires (null = never)"},"expired":{"type":"boolean","description":"Whether this token has expired"},"scopes":{"type":"array","items":{"type":"string"},"description":"Permission scopes granted to this token. ['*'] means full access."},"createdAt":{"type":"string","format":"date-time"},"max_per_tx":{"type":"number","nullable":true,"description":"Per-transaction spend cap in USD (null = uncapped)"},"max_per_month":{"type":"number","nullable":true,"description":"Rolling monthly spend cap in USD (null = uncapped)"},"spent_this_month":{"type":"number","description":"USD spent against the monthly cap this calendar month"},"parent_token_id":{"type":"string","nullable":true,"description":"Id of the token that minted this one (null = created via dashboard/session)"},"agent_identity":{"type":"object","nullable":true,"description":"Agent identity represented by this token. Its mail actions are attributed to this agent.","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"slug":{"type":"string"}}}},"required":["id","name","key","createdAt"]},"Contact":{"type":"object","description":"Contact information for a domain role (may be redacted due to GDPR/privacy services)","properties":{"name":{"type":"string","nullable":true,"description":"Contact name"},"organization":{"type":"string","nullable":true,"description":"Organization name"},"email":{"type":"string","nullable":true,"description":"Contact email"},"phone":{"type":"string","nullable":true,"description":"Phone number"},"fax":{"type":"string","nullable":true,"description":"Fax number"},"street":{"type":"string","nullable":true,"description":"Street address"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or province"},"postal_code":{"type":"string","nullable":true,"description":"Postal/ZIP code"},"country":{"type":"string","nullable":true,"description":"Country code or name"}}},"RegistrantContact":{"type":"object","description":"WHOIS registrant contact information required for domain registration (ICANN requirement)","properties":{"first_name":{"type":"string","description":"First name"},"last_name":{"type":"string","description":"Last name"},"org_name":{"type":"string","nullable":true,"description":"Organization name (optional)"},"address1":{"type":"string","description":"Street address line 1"},"address2":{"type":"string","nullable":true,"description":"Street address line 2 (optional)"},"city":{"type":"string","description":"City"},"state":{"type":"string","description":"State or province"},"postal_code":{"type":"string","description":"Postal/ZIP code"},"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code (e.g. US, GB, FR)"},"phone":{"type":"string","description":"Phone in +CC.NUMBER format (e.g. +1.5551234567)"},"email":{"type":"string","format":"email","description":"Contact email address"}},"required":["first_name","last_name","address1","city","state","postal_code","country","phone","email"]},"AccountInfo":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"has_payment_method":{"type":"boolean","description":"Whether the user has a card on file (required before buying domains)"},"has_contact":{"type":"boolean","description":"Whether the user has set WHOIS contact info (required before purchasing domains)"},"contact":{"$ref":"#/components/schemas/RegistrantContact","description":"Registrant contact info (null if not set)"},"referral_code":{"type":"string","description":"Your unique referral code"},"referral_rate":{"type":"integer","description":"Commission percentage on referred purchases"},"balance":{"type":"number","description":"Marketplace credit balance in USD (earned from sales)"},"domain_count":{"type":"integer","description":"Number of domains owned"},"token_count":{"type":"integer","description":"Number of active API tokens"},"created_at":{"type":"string","format":"date-time"}},"required":["id","email","has_payment_method","has_contact","referral_code","referral_rate","domain_count","token_count","created_at"]}},"headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}}},"paths":{"/api/auth/register":{"post":{"operationId":"registerUser","summary":"Create a new account","description":"Creates a new user account and returns an API key. Use this key as a Bearer token for all authenticated endpoints. Each account also receives a unique referral code. Pass a `ref` code to permanently link the new user to a referrer - the referrer earns a commission on all future domain purchases by this user.","tags":["Authentication"],"security":[],"x-rateLimit":{"limit":5,"window":"1 minute","scope":"IP address"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/auth/register \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"dev@example.com\"}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","example":"dev@example.com"},"ref":{"type":"string","description":"Referral code - permanently links this user to the referrer. The referrer earns a commission on every domain purchase.","example":"x7k9m2"}},"required":["email"]},"example":{"email":"dev@example.com","ref":"x7k9m2"}}}},"responses":{"201":{"description":"Account created successfully","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string","description":"Your API key - save this securely"},"referral_code":{"type":"string","description":"Your unique referral code for earning commissions"},"has_payment_method":{"type":"boolean","description":"Whether the user has a card on file (always false for new accounts)"},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"}}}}},"example":{"api_key":"domani_sk_a1B2c3D4e5F6g7H8i9J0kLmN","referral_code":"x7k9m2","has_payment_method":false,"user":{"id":"cm5abc123","email":"dev@example.com"}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Email is required","code":"MISSING_PARAMETER","hint":"Provide an 'email' field in the request body","documentation_url":"https://domani.run/llms.txt"}}}},"409":{"description":"User already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"User already exists","code":"USER_EXISTS","hint":"Use POST /api/auth/login to sign in instead","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/auth/login":{"post":{"operationId":"loginUser","summary":"Send a magic link sign-in email","description":"Sends a sign-in link to the provided email. If the user doesn't exist, creates an account first. The magic link redirects to the dashboard with auth credentials. For programmatic API access, use POST /api/auth/register to get an API key directly.","tags":["Authentication"],"security":[],"x-rateLimit":{"limit":10,"window":"1 minute","scope":"IP address"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/auth/login \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"dev@example.com\"}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]},"example":{"email":"dev@example.com"}}}},"responses":{"200":{"description":"Magic link sent - check your email","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"message":{"type":"string"}}},"example":{"ok":true,"message":"Check your email for a sign-in link."}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Email is required","code":"MISSING_PARAMETER","hint":"Provide an 'email' field in the request body","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/auth/verify":{"get":{"operationId":"verifyMagicLink","summary":"Verify a magic link token","description":"Validates the magic link token and redirects to the dashboard with auth credentials. Used by the magic link email - not typically called by agents directly. Agents should use POST /api/auth/register instead.","tags":["Authentication"],"security":[],"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"Magic link token from email (base64url-encoded)"}],"responses":{"307":{"description":"Redirect to dashboard with auth credentials in query parameters"},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Token is required","code":"MISSING_PARAMETER","hint":"Include the 'token' query parameter","documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/me":{"get":{"operationId":"getAccount","summary":"Get current account details","description":"Returns the authenticated user's account information including email, payment status, contact info status, referral code, and usage counts. Agents should call this after authentication to check `has_payment_method` and `has_contact` before attempting purchases.","tags":["Account"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/me \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"Account details","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInfo"},"example":{"id":"cm5abc123","email":"dev@example.com","has_payment_method":true,"has_contact":true,"referral_code":"x7k9m2","referral_rate":20,"domain_count":3,"token_count":2,"created_at":"2025-01-15T10:30:00.000Z"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"put":{"operationId":"updateAccount","summary":"Update account preferences","description":"Update the authenticated user's account preferences such as preferred payment method.","tags":["Account"],"x-rateLimit":{"limit":20,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"preferred_payment_method":{"type":"string","enum":["card","usdc"],"nullable":true,"description":"Default payment method for purchases (card, usdc, or null for auto-select)"}},"required":["preferred_payment_method"]}}}},"responses":{"200":{"description":"Preferences updated","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"preferred_payment_method":{"type":"string","nullable":true},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"delete":{"operationId":"deleteAccount","summary":"Delete account (blocked while domains are held)","description":"Permanently delete the authenticated user's account, tokens, webhooks, mailboxes, and other application data. Registered domains are NOT deleted with the account: the request fails with 409 HAS_DOMAINS until every domain is transferred out. This action cannot be undone.","tags":["Account"],"x-rateLimit":{"limit":5,"window":"1 minute"},"responses":{"200":{"description":"Account deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"409":{"description":"Account still holds registered domains (HAS_DOMAINS) - transfer them out first"},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/me/contact":{"get":{"operationId":"getContact","summary":"Get registrant contact info","description":"Returns the authenticated user's WHOIS registrant contact information. Must be set before purchasing or transferring domains.","tags":["Account"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/me/contact \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"Contact information","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"has_contact":{"type":"boolean"},"contact":{"$ref":"#/components/schemas/RegistrantContact","nullable":true}}},"example":{"has_contact":true,"contact":{"first_name":"Jane","last_name":"Doe","address1":"123 Main St","city":"New York","state":"NY","postal_code":"10001","country":"US","phone":"+1.2125551234","email":"jane@example.com"}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"put":{"operationId":"setContact","summary":"Set registrant contact info","description":"Set or update your WHOIS registrant contact information. Required by ICANN before purchasing domains. Used as the domain registrant and billing contact. When updated, the new contact is automatically propagated to all active domains at registrars that support contact updates.","tags":["Account"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X PUT https://domani.run/api/me/contact \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"first_name\":\"Jane\",\"last_name\":\"Doe\",\"address1\":\"123 Main St\",\"city\":\"New York\",\"state\":\"NY\",\"postal_code\":\"10001\",\"country\":\"US\",\"phone\":\"+1.2125551234\",\"email\":\"jane@example.com\"}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrantContact"}}}},"responses":{"200":{"description":"Contact info saved","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"contact":{"$ref":"#/components/schemas/RegistrantContact"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Missing required field: first_name","code":"INVALID_CONTACT","hint":"All required fields must be provided. Phone format: \"+CC.NUMBER\"","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/me/resend-verification":{"post":{"operationId":"resendEmailVerification","summary":"Resend contact email verification","description":"Resend the verification email for the account's contact email address. Rate limited to once per 15 minutes per email.","tags":["Account"],"x-rateLimit":{"limit":4,"window":"1 minute"},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email address to verify (defaults to account contact email)"}}}}}},"responses":{"200":{"description":"Verification email sent or already verified","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean"},"already_verified":{"type":"boolean"},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/tlds":{"get":{"operationId":"listTlds","summary":"List all available TLDs with pricing","description":"Returns all 1014+ available TLDs with registration, renewal, and transfer pricing. Supports filtering by price range, searching by TLD name, sorting, and pagination via `limit`/`offset`. When paginated, includes a `Link` header with the next page URL. **Public endpoint** - no authentication required. Authenticated requests get higher rate limits (60/min vs 30/min).","tags":["TLDs"],"security":[],"x-rateLimit":{"limit":30,"window":"1 minute","scope":"IP address (unauthenticated), 60/min per user (authenticated)"},"x-codeSamples":[{"lang":"bash","label":"cURL - cheap TLDs sorted by price","source":"curl https://domani.run/api/tlds?max_price=10&sort=price"}],"parameters":[{"name":"max_price","in":"query","schema":{"type":"number","example":15},"description":"Maximum registration price in USD"},{"name":"min_price","in":"query","schema":{"type":"number","example":1},"description":"Minimum registration price in USD"},{"name":"sort","in":"query","schema":{"type":"string","enum":["tld","price","renewal"],"default":"tld"},"description":"Sort field - 'tld' (alphabetical), 'price' (registration), or 'renewal'"},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"asc"},"description":"Sort order"},{"name":"search","in":"query","schema":{"type":"string","example":"dev"},"description":"Filter TLD names containing this string"},{"name":"limit","in":"query","schema":{"type":"integer","example":20},"description":"Max results per page"},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"example":0},"description":"Number of results to skip"}],"responses":{"200":{"description":"Paginated TLD list with pricing","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Link":{"description":"Pagination link (rel=\"next\") - present when more results exist","schema":{"type":"string"},"example":"</api/tlds?limit=20&offset=20&sort=price>; rel=\"next\""}},"content":{"application/json":{"schema":{"type":"object","properties":{"tlds":{"type":"array","items":{"$ref":"#/components/schemas/TldInfo"}},"total":{"type":"integer","description":"Total matching TLDs (before pagination)"},"offset":{"type":"integer"},"limit":{"type":"integer","nullable":true}}},"example":{"tlds":[{"tld":"xyz","registration":4.04,"renewal":4.04,"transfer":4.04},{"tld":"com","registration":10.88,"renewal":13.08,"transfer":13.08},{"tld":"dev","registration":15.85,"renewal":15.85,"transfer":15.85}],"total":1014,"offset":0,"limit":null}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/search":{"get":{"operationId":"search","summary":"Check availability and pricing for domains","description":"Checks availability and pricing for one or more domains via RDAP + retail pricing. Use `q` for a single domain (returns flat object) or `domains` for multiple (returns array). Supports SSE streaming via `Accept: text/event-stream` header - closing the connection cancels all in-flight RDAP lookups server-side. Max 200 domains per request. **Public endpoint** - no authentication required. Authenticated requests get higher rate limits (60/min vs 20/min).","tags":["Domain Search"],"security":[],"x-rateLimit":{"limit":20,"window":"1 minute","scope":"IP address (unauthenticated), 60/min per user (authenticated)"},"x-codeSamples":[{"lang":"bash","label":"Single domain","source":"curl \"https://domani.run/api/domains/search?q=mysite.com\""},{"lang":"bash","label":"Multiple domains","source":"curl \"https://domani.run/api/domains/search?domains=myapp.com,myapp.dev,myapp.ai&max_price=20\""},{"lang":"bash","label":"SSE streaming","source":"curl -H \"Accept: text/event-stream\" \"https://domani.run/api/domains/search?domains=myapp.com,myapp.dev,myapp.ai\""}],"parameters":[{"name":"q","in":"query","schema":{"type":"string","example":"mysite.com"},"description":"Single domain including TLD (shorthand - returns flat object). Mutually exclusive with `domains`."},{"name":"domains","in":"query","schema":{"type":"string","example":"myapp.com,myapp.dev,myapp.ai"},"description":"Comma-separated list of full domain names to check (max 200). Returns array result."},{"name":"max_price","in":"query","schema":{"type":"number","example":20},"description":"Only include domains under this price (USD)"},{"name":"sort","in":"query","schema":{"type":"string","enum":["price","tld"],"default":"price"},"description":"Sort results by price or TLD name"},{"name":"source","in":"query","schema":{"type":"string","enum":["all","primary","secondary"],"default":"all"},"description":"Filter results by source: 'primary' (registrar availability only), 'secondary' (Domani marketplace listings only), or 'all' (both)"},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"Domain availability and pricing. Single domain (via `q`) returns a flat object. Multiple domains (via `domains`) returns `{ results, total, available }`. With `Accept: text/event-stream`, returns SSE events (`event: result` per domain, `event: done` with summary).","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResult"},"examples":{"single":{"summary":"Single domain (via ?q=)","value":{"available":true,"domain":"mysite.com","price":10.88,"currency":"USD"}},"multi":{"summary":"Multiple domains (via ?domains=)","value":{"results":[{"available":true,"domain":"myapp.xyz","price":4.04,"currency":"USD"},{"available":true,"domain":"myapp.com","price":10.88,"currency":"USD"},{"available":false,"domain":"myapp.dev","price":15.85,"currency":"USD","for_sale":{"price":2500,"currency":"USD","source":"Sedo","buyable":false,"url":"https://sedo.com/search/details/?domain=myapp.dev"}}],"total":3,"available":2}}}}}},"400":{"description":"Missing or invalid domain format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No query parameter","value":{"error":"Provide 'q' for a single domain or 'domains' for multiple","code":"MISSING_PARAMETER","hint":"Use ?q=example.com or ?domains=example.com,example.dev","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Missing TLD","value":{"error":"Invalid domain format. Use: example.com","code":"INVALID_DOMAIN","hint":"Include TLD, e.g. mysite.com not just mysite","documentation_url":"https://domani.run/llms.txt"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/suggest":{"get":{"operationId":"suggestDomains","summary":"AI-powered domain suggestions with availability","description":"Given a project description, generates full domain names with creative TLDs (e.g. codebuddy.dev, wavify.fm), checks availability, and returns only available domains with pricing. Uses an agentic loop that retries until enough available domains are found. Supports SSE streaming via `Accept: text/event-stream` - closing the connection cancels in-flight LLM generation and RDAP lookups server-side. **Public endpoint** - no authentication required.","tags":["Domain Search"],"security":[],"x-rateLimit":{"limit":10,"window":"1 minute","scope":"IP address"},"x-codeSamples":[{"lang":"bash","label":"cURL (JSON)","source":"curl \"https://domani.run/api/domains/suggest?prompt=AI+coding+assistant\""},{"lang":"bash","label":"cURL (SSE)","source":"curl \"https://domani.run/api/domains/suggest?prompt=AI+coding+assistant\" -H \"Accept: text/event-stream\""}],"parameters":[{"name":"prompt","in":"query","required":true,"schema":{"type":"string","example":"AI coding assistant","minLength":3},"description":"Project description or keywords to generate domain suggestions from (min 3 characters)"},{"name":"count","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":20,"default":10},"description":"Number of available domains to return (default 10)"},{"name":"exclude","in":"query","required":false,"schema":{"type":"string","example":"codebuddy.dev,aiforge.sh"},"description":"Comma-separated list of domains to exclude from suggestions (e.g. from a previous batch)"},{"name":"tlds","in":"query","required":false,"schema":{"type":"string","example":"com,dev,ai"},"description":"Comma-separated preferred TLDs (without dots). Results will strongly favor these TLDs."},{"name":"style","in":"query","required":false,"schema":{"type":"string","enum":["single","creative","short","brandable","keyword"]},"description":"Name style preference: 'single' (one word), 'creative' (evocative/metaphorical), 'short' (3-6 chars), 'brandable' (invented), 'keyword' (descriptive)."},{"name":"lang","in":"query","required":false,"schema":{"type":"string","enum":["japanese","spanish","french","italian","latin","nordic","arabic","sanskrit"]},"description":"Language/cultural inspiration for names. Names will draw from this language's words, aesthetics, and culture."}],"responses":{"200":{"description":"Available domain suggestions with pricing. With `Accept: text/event-stream`, streams SSE events: `suggestion` (each available domain), `checking` (batch being checked), `iteration` (loop round), `done` (summary), `error`.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"suggestions":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string","description":"Full domain name with TLD"},"price":{"type":"number","description":"Registration price in USD"},"currency":{"type":"string","description":"Currency code"}},"required":["domain","price","currency"]},"description":"Available domain names with pricing"},"checked":{"type":"integer","description":"Total domains checked"},"iterations":{"type":"integer","description":"Number of LLM rounds"}},"required":["suggestions","checked","iterations"]},"example":{"suggestions":[{"domain":"codebuddy.dev","price":13,"currency":"USD"},{"domain":"aiforge.sh","price":33,"currency":"USD"},{"domain":"devcraft.app","price":13,"currency":"USD"}],"checked":42,"iterations":2}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Prompt must be at least 3 characters","code":"INVALID_PARAMETER","hint":"Provide a longer description","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains":{"get":{"operationId":"listDomains","summary":"List all your registered domains","description":"Returns all domains owned by the authenticated user, ordered by purchase date (newest first). Includes domain name, status, purchase date, and expiration date.","tags":["Domains"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/domains \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"List of registered domains","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domains":{"type":"array","items":{"$ref":"#/components/schemas/DomainRecord"}}}},"example":{"domains":[{"domain":"mysite.com","status":"active","purchasedAt":"2025-01-15T10:30:00.000Z","expiresAt":"2026-01-15T10:30:00.000Z","emailEnabled":true,"emailVerified":true,"emailVerifiedAt":"2025-01-15T10:35:00.000Z","mailboxCount":2},{"domain":"myapp.dev","status":"active","purchasedAt":"2025-02-01T14:00:00.000Z","expiresAt":"2026-02-01T14:00:00.000Z","emailEnabled":false,"emailVerified":false,"emailVerifiedAt":null,"mailboxCount":0}]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/agents/identity":{"post":{"operationId":"claimIdentity","summary":"Claim a free agent identity (<handle>.domani.run)","description":"Gives an agent a free identity at `<slug>.domani.run` - a live profile page, no domain purchase, instantly. The frictionless way to start; upgrade to a real owned domain later. Requires `account:write`.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/agents/identity \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"slug\": \"myagent\", \"name\": \"My Agent\", \"bio\": \"I broker domains.\", \"emoji\": \"🤖\"}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","example":"myagent","description":"The handle - becomes <slug>.domani.run"},"name":{"type":"string","description":"Display name"},"bio":{"type":"string","maxLength":280},"emoji":{"type":"string","description":"Avatar emoji"},"email":{"type":"string","format":"email","description":"Public contact (e.g. your free @domani.run inbox)"},"links":{"type":"array","maxItems":6,"items":{"type":"object","properties":{"label":{"type":"string"},"url":{"type":"string"}}}}}},"example":{"slug":"myagent","name":"My Agent","bio":"I broker domains.","emoji":"🤖"}}}},"responses":{"200":{"description":"Identity claimed","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentIdentity"},"example":{"success":true,"id":"agent_abc123","slug":"myagent","url":"https://myagent.domani.run","page_url":"https://domani.run/agents/myagent","name":"My Agent","bio":"I broker domains.","emoji":"🤖","email":null,"links":[],"views":0,"created_at":"2026-07-11T00:00:00.000Z"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Invalid handle","code":"INVALID_SLUG","hint":"Use lowercase letters, numbers, hyphens (1-63 chars)","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"409":{"description":"Handle taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"myagent.domani.run is already taken. Try another handle.","code":"SLUG_TAKEN","hint":"Pick a different handle","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"get":{"operationId":"listIdentities","summary":"List your agent identities","description":"Lists the free identities (`<handle>.domani.run`) you've claimed. Requires `account:read`.","tags":["Domains"],"x-rateLimit":{"limit":60,"window":"1 minute"},"responses":{"200":{"description":"Your identities","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"identities":{"type":"array","items":{"$ref":"#/components/schemas/AgentIdentity"}}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/agents/identity/{slug}":{"patch":{"operationId":"updateIdentity","summary":"Update an agent identity","description":"Update a free identity's name/bio/emoji/email/links. Requires `account:write`.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","example":"myagent"},"description":"The handle to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"bio":{"type":"string"},"emoji":{"type":"string"},"email":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"url":{"type":"string"}}}}}},"example":{"bio":"Updated bio","emoji":"🚀"}}}},"responses":{"200":{"description":"Updated","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentIdentity"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Identity not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Identity not found","code":"NOT_FOUND","hint":"Verify the identity exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"delete":{"operationId":"releaseIdentity","summary":"Release an agent identity","description":"Releases a free identity handle so it's available again. Requires `account:write`.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","example":"myagent"},"description":"The handle to release"}],"responses":{"200":{"description":"Released","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"slug":{"type":"string"},"released":{"type":"boolean"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Identity not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Identity not found","code":"NOT_FOUND","hint":"Verify the identity exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/agents/provision":{"post":{"operationId":"provisionAgent","summary":"Provision a complete agent identity in one call","description":"Gives an AI agent a complete internet identity in a single request: buys the domain (if not already owned), sets up email DNS, creates a mailbox, and optionally registers a webhook for inbound email and domain events.\n\nThe domain purchase is the only step that can charge and the only hard prerequisite - if it fails, the whole call fails (402 for payment, 409 if taken by another account). Email setup, mailbox creation, and webhook registration are best-effort: transient issues (e.g. DNS still propagating) are returned in `warnings` rather than failing the call, so the agent always gets its domain.\n\nPayment works exactly like POST /api/domains/buy (card, marketplace balance, or USDC via the `PAYMENT-SIGNATURE` header / two-step flow).","tags":["Domains"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/agents/provision \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"domain\": \"myagent.run\", \"slug\": \"hi\", \"webhook_url\": \"https://my-agent.example.com/inbox\"}'"}],"parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"type":"string"},"description":"Base64-encoded x402 payment payload (USDC on Base) to pay for the domain with USDC."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","example":"myagent.run","description":"Domain to give the agent. Bought if not already owned."},"slug":{"type":"string","example":"hi","description":"Mailbox local part (hi@domain). Default 'hi'."},"name":{"type":"string","description":"Display name for outbound email."},"webhook_url":{"type":"string","format":"uri","description":"Optional HTTPS URL to receive inbound email + domain events."},"webhook_events":{"type":"array","items":{"type":"string"},"description":"Webhook event types. Defaults to email.received/delivered/bounced."},"payment_method":{"type":"string","enum":["card","usdc","balance"],"description":"How to pay for the domain."},"payment_tx":{"type":"string","description":"USDC tx hash (two-step flow)."},"payment_chain":{"type":"string","enum":["base","ethereum"]},"years":{"type":"integer","minimum":1,"maximum":10,"default":1}}},"examples":{"minimal":{"summary":"Domain + default mailbox","value":{"domain":"myagent.run"}},"full":{"summary":"With mailbox slug and webhook","value":{"domain":"myagent.run","slug":"hi","name":"My Agent","webhook_url":"https://my-agent.example.com/inbox"}}}}}},"responses":{"200":{"description":"Agent provisioned (domain already owned)"},"201":{"description":"Agent provisioned (domain registered)","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"domain_status":{"type":"string","enum":["registered","owned"]},"mailbox":{"type":"object","nullable":true,"properties":{"address":{"type":"string"},"status":{"type":"string"}}},"webhook":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"url":{"type":"string"},"secret":{"type":"string"}}},"warnings":{"type":"array","items":{"type":"string"}},"hint":{"type":"string"},"next_steps":{"type":"array","items":{"type":"string"}}},"required":["domain","domain_status","warnings","hint","next_steps"]}}}},"402":{"description":"Payment required for the domain"},"409":{"description":"Domain is registered to another account"}}}},"/api/backorders":{"post":{"operationId":"createBackorder","summary":"Place a backorder on a taken domain","description":"Watches a domain that is currently registered to someone else and automatically registers it for you when it becomes available (drops) - availability is polled every few minutes, so the catch lands within minutes of the drop. You are charged only if and when the catch succeeds - no upfront fee. A price cap protects you from a registration-price spike between now and the drop.\n\nRequires a payment method on file (card) or `payment_method: \"balance\"` so the catch can be paid when it happens. Best-effort: a contested drop may be taken by a specialized drop-catcher first.","tags":["Backorders"],"x-rateLimit":{"limit":20,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/backorders \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"domain\": \"taken.com\"}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","example":"taken.com","description":"The currently-registered domain to watch and catch on drop."},"max_price":{"type":"number","description":"Max USD you'll pay to catch it. Defaults to the current registration price. Must be >= the current price."},"payment_method":{"type":"string","enum":["card","balance"],"description":"How to pay when caught. Defaults to your preferred method."}}},"examples":{"simple":{"summary":"Watch a domain","value":{"domain":"taken.com"}},"capped":{"summary":"With a price cap and balance","value":{"domain":"taken.com","max_price":25,"payment_method":"balance"}}}}}},"responses":{"201":{"description":"Backorder placed","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"backorder":{"$ref":"#/components/schemas/Backorder"},"hint":{"type":"string"}}}}}},"400":{"description":"Domain is available now (buy it directly), TLD unsupported, or invalid input"},"402":{"description":"A payment method is required to place the backorder"},"409":{"description":"You already have an active backorder on this domain, or the active-backorder limit was reached"}}},"get":{"operationId":"listBackorders","summary":"List your backorders","description":"Returns your backorders, newest first. Filter by `status` (watching, caught, failed, cancelled, expired).","tags":["Backorders"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["watching","caught","failed","cancelled","expired"]},"description":"Filter by status."}],"responses":{"200":{"description":"Your backorders","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"backorders":{"type":"array","items":{"$ref":"#/components/schemas/Backorder"}}}}}}}}}},"/api/backorders/{id}":{"get":{"operationId":"getBackorder","summary":"Get a backorder","tags":["Backorders"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Backorder ID."}],"responses":{"200":{"description":"The backorder","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"backorder":{"$ref":"#/components/schemas/Backorder"}}}}}},"404":{"description":"Backorder not found"}}},"delete":{"operationId":"cancelBackorder","summary":"Cancel a backorder","description":"Stops watching a domain. Only backorders in the `watching` state can be cancelled.","tags":["Backorders"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Backorder ID."}],"responses":{"200":{"description":"Backorder cancelled","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"hint":{"type":"string"}}}}}},"404":{"description":"Backorder not found"},"409":{"description":"Backorder is not in the watching state"}}}},"/api/domains/buy":{"post":{"operationId":"buyDomain","summary":"Purchase one or more domains","description":"Purchases one or more domains and registers them immediately. Send `{\"domain\": \"...\"}` for single or `{\"domains\": [\"...\", \"...\"]}` for bulk (max 10).\n\nIf the domain is listed for sale on the Domani marketplace, this endpoint automatically routes to a marketplace purchase instead of a fresh registration. The response includes `years: 0` and `marketplace_purchase: true` to distinguish it from a registration. Marketplace purchases are single-domain only. The buyer pays the full listed price; the seller receives the price minus a platform commission (default 10%).\n\nBulk purchases process each domain independently - failures don't block other purchases. The response includes `results` (succeeded), `errors` (failed), and `summary` with counts.\n\nAccepts three payment methods:\n\n1. **Card** (default): Requires a card on file via POST /api/billing/setup. Charged per domain.\n2. **USDC (two-step)**: First call without payment to get a 402 with `payment_options.crypto` (wallet address, amount, chains). Send USDC on-chain, then retry with `payment_tx` and `payment_chain` in the request body.\n3. **x402 USDC** (atomic): Include a `PAYMENT-SIGNATURE` header with a signed USDC payment on Base.\n\nBulk purchases require a card on file (USDC not supported for multi-domain). If no payment is provided for single domain, returns HTTP 402 with payment instructions.","tags":["Domains"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/domains/buy \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"domain\": \"mysite.com\"}'"}],"parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"type":"string"},"description":"Base64-encoded x402 payment payload (USDC on Base). When provided, the domain is paid with USDC instead of a card. x402-compatible clients handle this automatically after receiving a 402 response."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","example":"mysite.com","description":"Single domain to purchase (e.g. mysite.com)"},"domains":{"type":"array","items":{"type":"string"},"example":["mysite.com","mysite.dev"],"description":"Array of domains to purchase (max 10, requires card on file)"},"payment_method":{"type":"string","enum":["card","usdc","balance"],"description":"Payment method: 'card' (default), 'usdc' (x402 - first call returns 402 with payment instructions), or 'balance' (spend marketplace credit)."},"payment_tx":{"type":"string","description":"Transaction hash of a USDC payment already sent on-chain. Required on the second call of the two-step USDC flow."},"payment_chain":{"type":"string","enum":["base","ethereum"],"description":"Chain the USDC payment was sent on (e.g. 'base' or 'ethereum')."},"years":{"type":"integer","minimum":1,"maximum":10,"default":1,"description":"Number of years to register (1-10, default 1). Price is multiplied by years."},"max_price":{"type":"number","example":20,"description":"Ceiling in USD for the total charge. If the real price exceeds it, the request fails with 400 PRICE_ABOVE_MAX and nothing is charged - a safety belt for autonomous agents."},"ref":{"type":"string","description":"Referral code (optional) - the referrer earns a commission"}}},"examples":{"single":{"summary":"Single domain","value":{"domain":"mysite.com"}},"bulk":{"summary":"Multiple domains","value":{"domains":["mysite.com","mysite.dev","mysite.ai"]}}}}}},"responses":{"201":{"description":"Domain purchased and registered successfully","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["active"]},"expires":{"type":"string","format":"date-time"},"price":{"type":"number"},"currency":{"type":"string"},"years":{"type":"integer","description":"Number of years registered"},"payment_method":{"type":"string","enum":["card","x402","crypto"],"description":"How the domain was paid for"},"payment_tx":{"type":"string","description":"On-chain transaction hash (present for USDC payments)"},"marketplace_purchase":{"type":"boolean","description":"True when the domain was bought from the Domani marketplace (not a fresh registration)"}}},"examples":{"registration":{"summary":"Fresh registration","value":{"domain":"mysite.com","status":"active","expires":"2026-02-18T00:00:00.000Z","price":10.88,"currency":"USD","years":1,"payment_method":"card"}},"marketplace":{"summary":"Marketplace purchase","value":{"domain":"premium.com","status":"active","expires":null,"price":5000,"currency":"USD","years":0,"payment_method":"card","marketplace_purchase":true}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Valid domain is required","code":"INVALID_DOMAIN","hint":"Use format name.tld, e.g. mysite.com","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"402":{"description":"Payment required - includes x402 payment requirements for USDC on Base","headers":{"PAYMENT-REQUIRED":{"description":"Base64-encoded x402 payment requirements. x402-compatible clients decode this and auto-retry with a PAYMENT-SIGNATURE header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Payment required to register mysite.com","code":"PAYMENT_REQUIRED","hint":"Include a PAYMENT-SIGNATURE header with a signed USDC payment on Base, or set up a card via POST /api/billing/setup","documentation_url":"https://domani.run/llms.txt","x402":{"x402Version":2,"resource":{"url":"${APP_URL}/api/domains/buy","description":"Domain registration: mysite.com ($10.88)","mimeType":"application/json"},"accepts":[{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"10880000","payTo":"0x...","maxTimeoutSeconds":30}]}}}}},"409":{"description":"Domain is not available for registration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unavailable":{"summary":"Domain is taken","value":{"error":"Domain is not available","code":"DOMAIN_UNAVAILABLE","hint":"Try a different domain or TLD","documentation_url":"https://domani.run/llms.txt"}},"already_registered":{"summary":"Already in our system","value":{"error":"Domain already registered","code":"DOMAIN_UNAVAILABLE","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/dns":{"get":{"operationId":"getDnsRecords","summary":"Get DNS records for a domain you own","description":"Returns all DNS records configured for a domain you own (A, AAAA, CNAME, MX, TXT, NS, ...), each with a stable `id`, plus a `zone_version` token (also sent as the ETag header). Pass `zone_version` back on PUT to detect concurrent zone changes.","tags":["DNS"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/domains/mysite.com/dns \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"DNS records for the domain","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}},"zone_version":{"type":"string","description":"Optimistic-concurrency token for the whole zone. Pass it back on PUT (body zone_version or If-Match header) to fail with 409 DNS_VERSION_CONFLICT instead of clobbering a concurrent change."}}},"example":{"domain":"mysite.com","records":[{"id":"rec_1a2b3c4d5e6f","type":"A","name":"@","value":"76.76.21.21","ttl":3600},{"id":"rec_2b3c4d5e6f7a","type":"CNAME","name":"www","value":"mysite.com","ttl":3600},{"id":"rec_3c4d5e6f7a8b","type":"MX","name":"@","value":"mail.example.com","ttl":3600,"priority":10}],"zone_version":"zv_9f8e7d6c5b4a3f2e"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"put":{"operationId":"setDnsRecords","summary":"Set DNS records for a domain you own","description":"Upserts DNS records at the rrset level: for each (type, name) present in the payload, existing records at that (type, name) are replaced by the ones you send; rrsets NOT mentioned in the payload are preserved, and NS records are never touched. An automatic server-side backup of the zone is taken before every write.\n\nConcurrency: pass the `zone_version` from a prior GET (body field or If-Match header). If the zone changed since, the write fails with 409 DNS_VERSION_CONFLICT and returns the current records + version so you can re-merge and retry.","tags":["DNS"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL - point domain to Vercel","source":"curl -X PUT https://domani.run/api/domains/mysite.com/dns \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"records\": [\n    {\"type\": \"A\", \"name\": \"@\", \"value\": \"76.76.21.21\", \"ttl\": 3600},\n    {\"type\": \"CNAME\", \"name\": \"www\", \"value\": \"cname.vercel-dns.com\", \"ttl\": 3600}\n  ]}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}},"zone_version":{"type":"string","description":"The zone_version from a prior GET. On mismatch the write is rejected with 409 DNS_VERSION_CONFLICT (nothing written). Recommended whenever another actor may edit the same zone."}},"required":["records"]},"example":{"records":[{"type":"A","name":"@","value":"76.76.21.21","ttl":3600},{"type":"CNAME","name":"www","value":"cname.vercel-dns.com","ttl":3600}],"zone_version":"zv_9f8e7d6c5b4a3f2e"}}}},"responses":{"200":{"description":"DNS records updated successfully","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"domain":{"type":"string"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}}}},"example":{"success":true,"domain":"mysite.com","records":[{"type":"A","name":"@","value":"76.76.21.21","ttl":3600},{"type":"CNAME","name":"www","value":"cname.vercel-dns.com","ttl":3600}]}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Records array is required","code":"MISSING_PARAMETER","hint":"Provide a 'records' array in the request body","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"409":{"description":"zone_version mismatch (DNS_VERSION_CONFLICT) - the zone changed since your GET; the response carries current_records + current_zone_version to re-merge and retry"},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/dnssec":{"get":{"operationId":"getDnssecRecords","summary":"List DNSSEC DS records for a domain you own","description":"Returns the DNSSEC delegation-signer (DS) records published at the registry for a domain you own, and whether DNSSEC is enabled. Pairs with TLSA records (set via the DNS endpoint) for DANE.","tags":["DNS"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/domains/mysite.com/dnssec \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"DNSSEC DS records for the domain","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"enabled":{"type":"boolean","description":"True when at least one DS record is published"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DsRecord"}}}},"example":{"domain":"mysite.com","enabled":true,"records":[{"keyTag":"12345","algorithm":"13","digestType":"2","digest":"A1B2C3..."}]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"DNSSEC is in preview","code":"FEATURE_NOT_ENABLED","hint":"This feature is in preview - request access to enable it","documentation_url":"https://domani.run/llms.txt"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"post":{"operationId":"addDnssecRecord","summary":"Publish a DNSSEC DS record (enable DNSSEC)","description":"Publishes a delegation-signer (DS) record at the registry, enabling DNSSEC for the domain. Get the DS values from your DNS/zone provider after signing the zone.","tags":["DNS"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/domains/mysite.com/dnssec \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"keyTag\": \"12345\", \"algorithm\": \"13\", \"digestType\": \"2\", \"digest\": \"A1B2C3...\"}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DsRecord"},"example":{"keyTag":"12345","algorithm":"13","digestType":"2","digest":"A1B2C3..."}}}},"responses":{"200":{"description":"DS record published","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"domain":{"type":"string"},"enabled":{"type":"boolean"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DsRecord"}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Invalid DS record","code":"VALIDATION_ERROR","hint":"keyTag/algorithm/digestType must be numbers; digest must be hex","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"DNSSEC is in preview","code":"FEATURE_NOT_ENABLED","hint":"This feature is in preview - request access to enable it","documentation_url":"https://domani.run/llms.txt"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"delete":{"operationId":"deleteDnssecRecord","summary":"Remove a DNSSEC DS record (disable DNSSEC)","description":"Removes a delegation-signer (DS) record at the registry by its key tag. Removing all DS records disables DNSSEC for the domain.","tags":["DNS"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X DELETE \"https://domani.run/api/domains/mysite.com/dnssec?keyTag=12345\" \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"},{"name":"keyTag","in":"query","required":true,"schema":{"type":"string","example":"12345"},"description":"Key tag of the DS record to remove"}],"responses":{"200":{"description":"DS record removed","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"domain":{"type":"string"},"enabled":{"type":"boolean"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DsRecord"}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Missing keyTag","code":"INVALID_PARAMETER","hint":"Pass ?keyTag=12345","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"DNSSEC is in preview","code":"FEATURE_NOT_ENABLED","hint":"This feature is in preview - request access to enable it","documentation_url":"https://domani.run/llms.txt"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/dns/snapshot":{"post":{"operationId":"snapshotDns","summary":"Capture a DNS snapshot","description":"Captures all DNS records for a domain via public DNS lookups (Cloudflare DoH). Discovers subdomains from Certificate Transparency logs, SPF records, and common names. The snapshot is also stored server-side as a backup.","tags":["DNS"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/domains/mysite.com/dns/snapshot \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"extra_subdomains":{"type":"array","items":{"type":"string"},"description":"Additional subdomains to include in the snapshot"}}},"example":{"extra_subdomains":["api","cdn","staging"]}}}},"responses":{"200":{"description":"DNS snapshot captured","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}},"subdomains":{"type":"array","items":{"type":"string"}},"sources":{"type":"array","items":{"type":"string"}},"capturedAt":{"type":"string","format":"date-time"}}},"example":{"domain":"mysite.com","records":[{"type":"A","name":"@","value":"76.76.21.21","ttl":3600},{"type":"CNAME","name":"www","value":"mysite.com","ttl":3600},{"type":"MX","name":"@","value":"aspmx.l.google.com","ttl":3600,"priority":1}],"subdomains":["www","mail","api"],"sources":["ct","wordlist"],"capturedAt":"2026-03-06T12:00:00.000Z"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/dns/restore":{"post":{"operationId":"restoreDns","summary":"Restore DNS from a snapshot","description":"Applies DNS records from a snapshot to the domain's current registrar. Uses a diff algorithm to avoid duplicating records that already exist. If no snapshot is provided in the body, restores from the server-side backup (created by snapshot or transfer).","tags":["DNS"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL - restore from server backup","source":"curl -X POST https://domani.run/api/domains/mysite.com/dns/restore \\\n  -H \"Authorization: Bearer domani_sk_xxx\""},{"lang":"bash","label":"cURL - restore from local file","source":"curl -X POST https://domani.run/api/domains/mysite.com/dns/restore \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"snapshot\": '\"$(cat mysite.com.dns.json)\"'}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"snapshot":{"type":"object","description":"A DNS snapshot object (as returned by the snapshot endpoint). If omitted, the stored server-side backup is used.","properties":{"domain":{"type":"string"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}},"subdomains":{"type":"array","items":{"type":"string"}},"sources":{"type":"array","items":{"type":"string"}},"capturedAt":{"type":"string","format":"date-time"}}},"dry_run":{"type":"boolean","description":"Preview only: returns what the restore would create (would_apply) and skip, without writing anything."}}}}}},"responses":{"200":{"description":"DNS restored from snapshot","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"applied":{"type":"integer","description":"Number of records created"},"skipped":{"type":"integer","description":"Number of records already present"},"recordCount":{"type":"integer","description":"Total records in the snapshot"},"errors":{"type":"array","items":{"type":"string"}},"dry_run":{"type":"boolean","description":"True when this was a preview - nothing was written"},"would_apply":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"},"description":"Dry run only: the records the restore would create"}}},"example":{"domain":"mysite.com","applied":5,"skipped":2,"recordCount":7,"errors":[]}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"No snapshot provided and no stored backup found","code":"NO_SNAPSHOT","hint":"Capture a snapshot first with POST /api/domains/:domain/dns/snapshot","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"409":{"description":"Domain not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain is not active","code":"DOMAIN_NOT_ACTIVE","hint":"Domain must be active to restore DNS"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/dns/clone":{"post":{"operationId":"cloneDns","summary":"Clone another domain's DNS onto this one","description":"Copies the DNS setup of a source domain you own onto this domain - useful for multi-TLD brands (brand.com → brand.dev) that share the same A/CNAME/MX. Merges by default (source records win on any type+name collision, this domain's other records are kept); set `replace: true` for an exact mirror.","tags":["DNS"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/domains/brand.dev/dns/clone \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"from\": \"brand.com\"}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"brand.dev"},"description":"Target domain (DNS is written here)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","example":"brand.com","description":"Source domain to copy DNS from (must be yours)"},"replace":{"type":"boolean","description":"Exact mirror - drop target records the source doesn't have. Default: merge"}},"required":["from"]},"example":{"from":"brand.com"}}}},"responses":{"200":{"description":"DNS cloned","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"from_domain":{"type":"string"},"to_domain":{"type":"string"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Source and target domain must differ","code":"INVALID_DOMAIN","hint":"Pass a different source domain in 'from'","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/nameservers":{"get":{"operationId":"getNameservers","summary":"Get nameservers for a domain","description":"Returns the authoritative nameservers configured for a domain you own. If empty, DNS operations (parking, email, connect) will fail until nameservers are assigned.","tags":["DNS"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/domains/mysite.com/nameservers \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Nameservers for the domain","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"nameservers":{"type":"array","items":{"type":"string"}},"default_nameservers":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Registrar default nameservers (null if unknown)"},"hint":{"type":"string"}}},"example":{"domain":"mysite.com","nameservers":["ns1.systemdns.com","ns2.systemdns.com","ns3.systemdns.com"],"default_nameservers":["ns1.systemdns.com","ns2.systemdns.com","ns3.systemdns.com"],"hint":"3 nameservers configured for mysite.com."}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"put":{"operationId":"setNameservers","summary":"Set nameservers for a domain","description":"Replace the nameservers for a domain you own. Requires 2–13 valid hostnames. Common values: OpenSRS DNS (ns1.systemdns.com, ns2.systemdns.com, ns3.systemdns.com).","tags":["DNS"],"x-rateLimit":{"limit":30,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X PUT https://domani.run/api/domains/mysite.com/nameservers \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"nameservers\": [\"ns1.systemdns.com\", \"ns2.systemdns.com\", \"ns3.systemdns.com\"]}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"nameservers":{"type":"array","items":{"type":"string"},"minItems":2,"maxItems":13,"description":"Nameserver hostnames (2–13 required)"}},"required":["nameservers"]},"example":{"nameservers":["ns1.systemdns.com","ns2.systemdns.com","ns3.systemdns.com"]}}}},"responses":{"200":{"description":"Nameservers updated successfully","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"domain":{"type":"string"},"nameservers":{"type":"array","items":{"type":"string"}},"hint":{"type":"string"}}},"example":{"success":true,"domain":"mysite.com","nameservers":["ns1.systemdns.com","ns2.systemdns.com","ns3.systemdns.com"],"hint":"Nameservers for mysite.com updated to ns1.systemdns.com, ns2.systemdns.com, ns3.systemdns.com. Changes may take up to 48 hours to propagate."}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"At least 2 nameservers required","code":"VALIDATION_ERROR","hint":"Provide 2–13 valid nameserver hostnames","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/connect":{"post":{"operationId":"connectDomain","summary":"Connect a domain to a hosting or email provider","description":"Connects a domain to a hosting or email provider by auto-detecting the provider from a target URL or accepting an explicit provider name.\n\nFor domains managed through the platform, DNS records are set automatically (status: `dns_set`). For imported domains (external registrar), returns the records as instructions to add manually at your registrar (status: `manual_setup_required`, records have status `pending`).\n\nSupported hosting providers: vercel, netlify, cloudflare-pages, github-pages, railway, fly.\nSupported email providers: google-workspace, fastmail, proton.\n\nUse `GET /api/domains/{domain}/connect` to list all available providers and methods.","tags":["Connect"],"x-rateLimit":{"limit":30,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL - auto-detect from target","source":"curl -X POST https://domani.run/api/domains/mysite.com/connect \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"target\": \"my-app.vercel.app\"}'"},{"lang":"bash","label":"cURL - explicit provider","source":"curl -X POST https://domani.run/api/domains/mysite.com/connect \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"provider\": \"google-workspace\"}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target":{"type":"string","description":"Target URL for auto-detection (e.g. my-app.vercel.app)","example":"my-app.vercel.app"},"provider":{"type":"string","description":"Explicit provider name (e.g. vercel, google-workspace)","example":"vercel"},"method":{"type":"string","description":"Connection method if provider has multiple (e.g. cname-only)"},"dry_run":{"type":"boolean","description":"Preview only: returns the diff (create/replace/already_set/keep) without writing anything."},"confirm_replace_mx":{"type":"boolean","description":"Required when the connect would replace existing MX records pointing at another provider (409 MX_REPLACEMENT_REQUIRES_CONFIRMATION otherwise) - it reroutes the domain's email."}}},"examples":{"autoDetect":{"summary":"Auto-detect from target","value":{"target":"my-app.vercel.app"}},"explicit":{"summary":"Explicit provider","value":{"provider":"google-workspace"}},"withMethod":{"summary":"Provider with specific method","value":{"provider":"netlify","method":"cname-only"}}}}}},"responses":{"200":{"description":"Domain connected or DNS instructions returned","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"provider":{"type":"string"},"category":{"type":"string","enum":["hosting","email"]},"method":{"type":"string"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}},"docs":{"type":"string","format":"uri"},"status":{"type":"string","enum":["dns_set","manual_setup_required","dry_run"],"description":"dns_set = records written automatically. manual_setup_required = imported domain, add records at your registrar. dry_run = preview only, nothing written."},"hint":{"type":"string"},"next_steps":{"type":"array","items":{"type":"string"},"description":"Provider-specific actions to complete after DNS records are set"},"diff":{"type":"object","description":"Dry run only: what the write would do - create, replace (existing records that would be removed), already_set, keep (untouched rrsets)."}}},"examples":{"managed":{"summary":"Managed domain (DNS set automatically)","value":{"domain":"mysite.com","provider":"vercel","category":"hosting","method":"recommended","records":[{"record":{"type":"A","name":"@","value":"76.76.21.21","ttl":3600},"status":"created"},{"record":{"type":"CNAME","name":"www","value":"cname.vercel-dns.com","ttl":3600},"status":"created"}],"docs":"https://vercel.com/docs/projects/domains","status":"dns_set","hint":"Add mysite.com to your Vercel project: run `npx vercel domains add mysite.com` in your project directory, or add it in Project Settings > Domains on vercel.com","next_steps":["Add mysite.com to your Vercel project: run `npx vercel domains add mysite.com` in your project directory, or add it in Project Settings > Domains on vercel.com","DNS propagation may take up to 48 hours. Verify with POST /api/domains/mysite.com/verify"]}},"imported":{"summary":"Imported domain (manual DNS setup required)","value":{"domain":"mysite.com","provider":"vercel","category":"hosting","method":"recommended","records":[{"record":{"type":"A","name":"@","value":"76.76.21.21","ttl":3600},"status":"pending"},{"record":{"type":"CNAME","name":"www","value":"cname.vercel-dns.com","ttl":3600},"status":"pending"}],"docs":"https://vercel.com/docs/projects/domains","status":"manual_setup_required","hint":"Add the DNS records above at your current registrar (Namecheap, GoDaddy, Cloudflare, etc.)","next_steps":["Add the DNS records above at your current registrar (Namecheap, GoDaddy, Cloudflare, etc.)","Add mysite.com to your Vercel project: run `npx vercel domains add mysite.com` in your project directory, or add it in Project Settings > Domains on vercel.com","DNS propagation may take up to 48 hours. Verify with POST /api/domains/mysite.com/verify"]}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Either 'target' or 'provider' is required","code":"MISSING_PARAMETER","hint":"Pass { target: 'my-app.vercel.app' } or { provider: 'vercel' }","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"get":{"operationId":"listConnectProviders","summary":"List available providers for connecting a domain","description":"Returns all supported hosting and email providers with their connection methods. Use this to discover what providers are available before calling POST.","tags":["Connect"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Available providers grouped by category","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"providers":{"type":"object","properties":{"hosting":{"type":"array","items":{"type":"object","description":"Provider with name, category, patterns, requires_target, notes, methods, docs"}},"email":{"type":"array","items":{"type":"object","description":"Provider with name, category, patterns, requires_target, notes, methods, docs"}}}}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"409":{"description":"Existing MX records would be replaced (MX_REPLACEMENT_REQUIRES_CONFIRMATION) - preview with dry_run, then retry with confirm_replace_mx: true"},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/status":{"get":{"operationId":"getDomainStatus","summary":"Check domain health: DNS, SSL, email, expiry","description":"Checks the health of a domain via DNS-over-HTTPS: A/AAAA/CNAME/MX/TXT/NS records, SSL certificate status, email configuration, and expiry date. Supports SSE streaming via `Accept: text/event-stream` - closing the connection cancels in-flight DNS/SSL checks server-side. Use this after connecting to verify DNS propagation.","tags":["Status"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/domains/mysite.com/status \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Domain health status","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string"},"expires":{"type":"string","format":"date-time"},"days_until_expiry":{"type":"integer"},"dns":{"type":"object","properties":{"propagated":{"type":"boolean"},"a":{"type":"array","items":{"type":"string"}},"aaaa":{"type":"array","items":{"type":"string"}},"cname":{"type":"array","items":{"type":"string"}},"mx":{"type":"array","items":{"type":"string"}},"txt":{"type":"array","items":{"type":"string"}},"ns":{"type":"array","items":{"type":"string"}},"registrar_records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}}}},"ssl":{"type":"object","properties":{"active":{"type":"boolean"}}},"email":{"type":"object","properties":{"configured":{"type":"boolean"},"mx":{"type":"array","items":{"type":"string"}}}}}},"example":{"domain":"mysite.com","status":"active","expires":"2027-02-18T00:00:00.000Z","days_until_expiry":365,"dns":{"propagated":true,"a":["76.76.21.21"],"aaaa":[],"cname":[],"mx":[],"txt":[],"ns":["ns1.porkbun.com","ns2.porkbun.com"],"registrar_records":[{"type":"A","name":"@","value":"76.76.21.21","ttl":3600}]},"ssl":{"active":true},"email":{"configured":false,"mx":[]}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/email/check":{"get":{"operationId":"checkEmail","summary":"Check email DNS health (MX, SPF, DMARC, DKIM)","description":"Checks email DNS configuration for a domain: MX records, SPF, DMARC, and DKIM. Auto-detects the email provider from MX records (Google Workspace, Proton, Fastmail).","tags":["Email"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/domains/mysite.com/email/check \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Email DNS health report","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"provider":{"type":"string","nullable":true,"description":"Auto-detected email provider (google-workspace, proton, fastmail) or null"},"mx":{"type":"object","properties":{"configured":{"type":"boolean"},"records":{"type":"array","items":{"type":"string"}}}},"spf":{"type":"object","properties":{"configured":{"type":"boolean"},"value":{"type":"string","nullable":true}}},"dmarc":{"type":"object","properties":{"configured":{"type":"boolean"},"value":{"type":"string","nullable":true}}},"dkim":{"type":"object","properties":{"configured":{"type":"boolean"},"selectors":{"type":"array","items":{"type":"string"}}}}}},"example":{"domain":"mysite.com","provider":"google-workspace","mx":{"configured":true,"records":["1 aspmx.l.google.com","5 alt1.aspmx.l.google.com"]},"spf":{"configured":true,"value":"v=spf1 include:_spf.google.com ~all"},"dmarc":{"configured":true,"value":"v=DMARC1; p=quarantine; rua=mailto:dmarc@mysite.com"},"dkim":{"configured":true,"selectors":["google"]}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/email/deliverability":{"get":{"operationId":"getEmailDeliverability","summary":"Get owner-scoped email deliverability health","description":"Separates deterministic authentication readiness, 30-day recipient-weighted delivery outcomes, account safety state, and measured provider placement. The readiness score is not an Inbox probability, and unmeasured placement is returned as not_tested.","tags":["Email"],"x-rateLimit":{"limit":30,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/domains/mysite.com/email/deliverability \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Domain email health report","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","required":["domain","status","confidence","checked_at","readiness","sending_health","placement","actions"],"properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["healthy","limited_data","needs_attention","at_risk","paused"]},"confidence":{"type":"string","enum":["none","limited","sufficient"]},"checked_at":{"type":"string","format":"date-time"},"window_days":{"type":"integer","example":30},"readiness":{"type":"object","description":"Deterministic DNS configuration readiness. Score is not an Inbox probability.","properties":{"score":{"type":"integer","minimum":0,"maximum":100},"configured":{"type":"integer"},"total":{"type":"integer","example":4},"provider":{"type":"string","nullable":true},"checks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"configured":{"type":"boolean"}}}}}},"sending_health":{"type":"object","properties":{"recipients":{"type":"object","additionalProperties":{"type":"integer"}},"rates":{"type":"object","properties":{"bounce":{"type":"number"},"complaint":{"type":"number"}}},"paused":{"type":"boolean"},"pause_reason":{"type":"string","nullable":true},"account_suppressions":{"type":"integer"}}},"placement":{"type":"object","properties":{"available":{"type":"boolean"},"last_checked_at":{"type":"string","format":"date-time","nullable":true},"providers":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","enum":["gmail","outlook","yahoo"]},"status":{"type":"string","enum":["inbox","spam","missing","not_tested"]}}}},"note":{"type":"string"}}},"actions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"severity":{"type":"string","enum":["info","warning","critical"]},"title":{"type":"string"},"detail":{"type":"string"}}}},"caveats":{"type":"array","items":{"type":"string"}}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/verify":{"post":{"operationId":"verifyConnection","summary":"Verify that a provider connection is working","description":"Runs the provider's verification check to confirm DNS records have propagated and the connection is active. Use after POST /api/domains/{domain}/connect to verify.","tags":["Connect"],"x-rateLimit":{"limit":30,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/domains/mysite.com/verify \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"target\": \"my-app.vercel.app\"}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target":{"type":"string","description":"Target for auto-detection"},"provider":{"type":"string","description":"Provider name"},"method":{"type":"string","description":"Method name"}}}}}},"responses":{"200":{"description":"Verification result","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"provider":{"type":"string"},"method":{"type":"string"},"verified":{"type":"boolean"},"message":{"type":"string"},"hint":{"type":"string"},"next_steps":{"type":"array","items":{"type":"string"},"description":"Provider-specific troubleshooting steps (only when verified is false)"}}},"examples":{"verified":{"summary":"Connection verified","value":{"domain":"mysite.com","provider":"vercel","method":"recommended","verified":true,"message":"DNS records verified - connection is active"}},"pending":{"summary":"DNS not yet propagated","value":{"domain":"mysite.com","provider":"vercel","method":"recommended","verified":false,"message":"DNS records not yet propagated","hint":"Ensure you completed the provider-side setup: Add mysite.com to your Vercel project: run `npx vercel domains add mysite.com` in your project directory, or add it in Project Settings > Domains on vercel.com","next_steps":["Ensure you completed the provider-side setup: Add mysite.com to your Vercel project: run `npx vercel domains add mysite.com` in your project directory, or add it in Project Settings > Domains on vercel.com","DNS propagation can take up to 48 hours. Try again later."]}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Either 'target' or 'provider' is required","code":"MISSING_PARAMETER","hint":"Pass the same target/provider you used when connecting","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/verify-service":{"post":{"operationId":"verifyService","summary":"Add DNS records to verify domain ownership for a third-party service","description":"Adds the correct DNS records (TXT, CNAME) to prove domain ownership to a third-party service. Supports Stripe, Google Search Console, AWS SES, Postmark, Resend, Facebook, HubSpot, and Microsoft 365. Unknown service names fall back to a generic TXT record.\n\nRecords are merged with existing DNS - existing records are preserved.","tags":["Verify Service"],"x-rateLimit":{"limit":30,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL - Stripe verification","source":"curl -X POST https://domani.run/api/domains/mysite.com/verify-service \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"service\": \"stripe\", \"token\": \"abc123def456\"}'"},{"lang":"bash","label":"cURL - Google Search Console","source":"curl -X POST https://domani.run/api/domains/mysite.com/verify-service \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"service\": \"google-search-console\", \"token\": \"abcdef123456\"}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["service","token"],"properties":{"service":{"type":"string","description":"Service name (e.g. stripe, google-search-console, aws-ses, postmark, resend, facebook, hubspot, microsoft-365)","example":"stripe"},"token":{"type":"string","description":"Verification token provided by the service","example":"abc123def456"}}},"examples":{"stripe":{"summary":"Stripe","value":{"service":"stripe","token":"abc123def456"}},"google":{"summary":"Google Search Console","value":{"service":"google-search-console","token":"abcdef123456"}},"aws":{"summary":"AWS SES","value":{"service":"aws-ses","token":"EXAMPLE+abc123"}},"generic":{"summary":"Generic (any service)","value":{"service":"my-saas","token":"verify-my-domain-xyz"}}}}}},"responses":{"200":{"description":"Verification records added","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"service":{"type":"string"},"service_display_name":{"type":"string"},"known_service":{"type":"boolean"},"records_added":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}},"total_records":{"type":"integer"},"docs":{"type":"string","format":"uri","nullable":true},"hint":{"type":"string"}}},"example":{"domain":"mysite.com","service":"stripe","service_display_name":"Stripe","known_service":true,"records_added":[{"type":"TXT","name":"@","value":"stripe-verification=abc123def456","ttl":3600}],"total_records":3,"docs":"https://docs.stripe.com/identity/verification-checks/selfie#domain-verification","hint":"Stripe verification records added. Return to Stripe to complete verification."}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Missing 'service' parameter","code":"MISSING_PARAMETER","hint":"Send { service: 'stripe', token: 'your-token' }","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"get":{"operationId":"listVerifyServices","summary":"List supported services for domain verification","description":"Returns all known services with their names, descriptions, and documentation URLs. Unknown services fall back to a generic TXT record.","tags":["Verify Service"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Available services","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"services":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"},"description":{"type":"string"},"docs":{"type":"string","format":"uri"}}}},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}":{"get":{"operationId":"getDomainInfo","summary":"Get detailed information about a domain you own","description":"Returns comprehensive information about a domain: status, purchase date, expiry, payment method, security lock, WHOIS privacy, auto-renew status, and registration dates. The `registrar` object may be `null` if extended data is unavailable.","tags":["Domains"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/domains/mysite.com \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Domain details","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainDetail"},"example":{"domain":"mysite.com","status":"active","auto_renew":true,"purchased_at":"2025-06-01T12:00:00.000Z","expires_at":"2026-06-01T12:00:00.000Z","days_until_expiry":365,"payment_method":"card","registrar_status":"connected","registrar_checked_at":"2025-06-01T12:00:00.000Z","registrar":{"security_lock":true,"whois_privacy":true,"auto_renew":true,"create_date":"2025-06-01T12:00:00Z","expire_date":"2026-06-01T12:00:00Z"}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/settings":{"put":{"operationId":"updateDomainSettings","summary":"Update domain settings","description":"Update settings for a domain you own. Supports `auto_renew`, `whois_privacy`, and `security_lock`. At least one field must be provided.","tags":["Domains"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL - Disable auto-renew","source":"curl -X PUT https://domani.run/api/domains/mysite.com/settings \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"auto_renew\": false}'"},{"lang":"bash","label":"cURL - Enable auto-renew","source":"curl -X PUT https://domani.run/api/domains/mysite.com/settings \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"auto_renew\": true}'"},{"lang":"bash","label":"cURL - Enable WHOIS privacy","source":"curl -X PUT https://domani.run/api/domains/mysite.com/settings \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"whois_privacy\": true}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"auto_renew":{"type":"boolean","description":"Whether to enable auto-renew for this domain"},"whois_privacy":{"type":"boolean","description":"Whether to enable WHOIS privacy protection"},"security_lock":{"type":"boolean","description":"Whether to lock the domain against transfers"}}},"examples":{"disable":{"summary":"Disable auto-renew","value":{"auto_renew":false}},"enable":{"summary":"Enable auto-renew","value":{"auto_renew":true}},"privacy":{"summary":"Enable WHOIS privacy","value":{"whois_privacy":true}},"unlock":{"summary":"Unlock for transfer","value":{"security_lock":false}}}}}},"responses":{"200":{"description":"Settings updated","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"auto_renew":{"type":"boolean"},"whois_privacy":{"type":"boolean"},"security_lock":{"type":"boolean"},"hint":{"type":"string"}},"required":["domain","hint"]},"examples":{"disabled":{"summary":"Auto-renew disabled","value":{"domain":"mysite.com","auto_renew":false,"hint":"Auto-renew is now disabled. Remember to renew manually before the domain expires."}},"enabled":{"summary":"Auto-renew enabled","value":{"domain":"mysite.com","auto_renew":true,"hint":"Auto-renew is now enabled. The domain will be renewed automatically before expiry."}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"auto_renew must be a boolean","code":"INVALID_PARAMETER","hint":"Send { \"auto_renew\": true } or { \"auto_renew\": false }","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/parking":{"put":{"operationId":"updateParking","summary":"Update parking settings","description":"Update parking and listing settings for a domain you own. Enable/disable the parking page and set a 'For Sale' listing price. When parking is enabled, visitors to the domain see a branded page. When a listing price is set, visitors see a 'For Sale' page with a contact form.","tags":["Domains"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether to enable the parking page"},"listing_price":{"type":"number","nullable":true,"description":"Sale price in USD, or null to remove listing"}}},"examples":{"enable":{"summary":"Enable parking","value":{"enabled":true}},"disable":{"summary":"Disable parking","value":{"enabled":false}},"list":{"summary":"List for sale","value":{"listing_price":499.99}},"unlist":{"summary":"Remove listing","value":{"listing_price":null}}}}}},"responses":{"200":{"description":"Parking settings updated","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"parking_enabled":{"type":"boolean"},"listing_price":{"type":"number","nullable":true},"hint":{"type":"string"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"No parking settings provided","code":"INVALID_PARAMETER","hint":"Send { \"enabled\": true/false, \"listing_price\": 499.99 }","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/redirect":{"put":{"operationId":"setDomainRedirect","summary":"Forward a domain to a URL","description":"Forward a domain you own to another URL (e.g. brand.com -> https://brand.dev) - useful for multi-TLD brands. The domain must point at domani's nameservers/parking IP for the redirect to serve. Permanent (308) by default or temporary (307). Requires `domains:write` scope.","tags":["Domains"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"Target URL (or bare domain) to forward to, e.g. https://brand.dev"},"permanent":{"type":"boolean","description":"true = permanent (308, default), false = temporary (307)"}}},"example":{"url":"https://brand.dev","permanent":true}}}},"responses":{"200":{"description":"Redirect set","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"redirect_url":{"type":"string","nullable":true},"permanent":{"type":"boolean"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Invalid URL","code":"INVALID_URL","hint":"Provide a valid http(s) URL like https://example.com","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"delete":{"operationId":"clearDomainRedirect","summary":"Stop forwarding a domain","description":"Remove a domain's redirect so it reverts to the parking page. Requires `domains:write` scope.","tags":["Domains"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"responses":{"200":{"description":"Redirect cleared","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"redirect_url":{"type":"string","nullable":true}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/for-sale":{"put":{"operationId":"createListing","summary":"List a domain for sale","description":"List a domain you own for sale on the Domani marketplace. Buyers can purchase it directly via the API. The domain must be active and not already listed.\n\n**Fees:** Domani charges a platform commission (default 10%) on successful sales. The seller receives the listed price minus the commission. The buyer pays the full listed price.\n\nRequires `domains:write` scope.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name to list for sale"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"price":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":100000000,"description":"Sale price in USD"},"description":{"type":"string","maxLength":500,"description":"Optional listing description"}},"required":["price"]},"examples":{"basic":{"summary":"List for $5,000","value":{"price":5000}},"withDescription":{"summary":"With description","value":{"price":5000,"description":"Premium .com domain, established 2010"}}}}}},"responses":{"200":{"description":"Domain listed for sale","content":{"application/json":{"schema":{"type":"object","properties":{"listing":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"price":{"type":"number"},"currency":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string","enum":["active"]},"created_at":{"type":"string","format":"date-time"}}},"hint":{"type":"string"}}},"example":{"listing":{"id":"lst_abc123","domain":"example.com","price":5000,"currency":"USD","description":null,"status":"active","created_at":"2026-03-14T12:00:00.000Z"},"hint":"example.com listed for sale at $5,000. Buyers can purchase it on the marketplace."}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain already listed for sale. Cancel the existing listing first.","code":"ALREADY_LISTED","hint":"Use DELETE /api/domains/{domain}/for-sale to cancel","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"patch":{"operationId":"updateListing","summary":"Update a domain listing","description":"Update the price and/or description of an active marketplace listing. At least one field must be provided. Requires `domains:write` scope.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name with active listing"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"price":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":100000000,"description":"New sale price in USD"},"description":{"type":"string","maxLength":500,"nullable":true,"description":"New description (null to clear)"}}},"examples":{"updatePrice":{"summary":"Update price","value":{"price":7000}},"updateDescription":{"summary":"Update description","value":{"description":"Premium domain, established 2010"}},"clearDescription":{"summary":"Clear description","value":{"description":null}}}}}},"responses":{"200":{"description":"Listing updated","content":{"application/json":{"schema":{"type":"object","properties":{"listing":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"price":{"type":"number"},"currency":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string","enum":["active"]},"created_at":{"type":"string","format":"date-time"}}},"hint":{"type":"string"}}},"example":{"listing":{"id":"lst_abc123","domain":"example.com","price":7000,"currency":"USD","description":"Premium domain","status":"active","created_at":"2026-03-14T12:00:00.000Z"},"hint":"Listing for example.com has been updated. New price: $7,000."}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Provide at least one field to update (price, description)","code":"MISSING_PARAMETER","hint":"Send at least 'price' and/or 'description' in the request body.","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Listing not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Listing not found","code":"NOT_FOUND","hint":"Verify the listing exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"delete":{"operationId":"cancelListing","summary":"Cancel a domain listing","description":"Remove an active for-sale listing for a domain you own. The domain remains in your account but is no longer available for purchase on the marketplace. Requires `domains:write` scope.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name to unlist"}],"responses":{"200":{"description":"Listing cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["cancelled"]},"hint":{"type":"string"}}},"example":{"domain":"example.com","status":"cancelled","hint":"Listing for example.com has been cancelled."}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Listing not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Listing not found","code":"NOT_FOUND","hint":"Verify the listing exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/sell":{"post":{"operationId":"sellDomain","summary":"List a domain for sale (open marketplace)","description":"List any domain for sale on the Domani marketplace, including domains on other registrars. Domains already in your Domani account are auto-verified and listed immediately (status `active`). External domains require TXT ownership verification (status `pending_verification`).\n\n**Fees:** 10% platform commission on successful sales.\n\nRequires `deals:write` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":30,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","description":"Domain name to list for sale"},"price":{"type":"number","minimum":0,"exclusiveMinimum":true,"maximum":100000000,"description":"Sale price in USD"},"description":{"type":"string","maxLength":500,"description":"Optional listing description"}},"required":["domain","price"]},"examples":{"internal":{"summary":"Domani-hosted domain","value":{"domain":"myproject.dev","price":5000}},"external":{"summary":"External domain","value":{"domain":"premium.io","price":25000,"description":"Premium brandable domain"}}}}}},"responses":{"201":{"description":"Domain listed (or pending verification for external domains)","content":{"application/json":{"schema":{"type":"object","properties":{"listing":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"price":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string","enum":["active","pending_verification"]},"description":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"txt_record":{"type":"object","nullable":true,"description":"TXT record to add for ownership verification (only for external domains)","properties":{"type":{"type":"string","enum":["TXT"]},"name":{"type":"string","example":"_domani-verify"},"value":{"type":"string"}}},"hint":{"type":"string"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain already listed for sale","code":"ALREADY_LISTED","hint":"Cancel the existing listing first with DELETE /api/domains/{domain}/for-sale","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/sell/verify":{"post":{"operationId":"verifySellListing","summary":"Verify TXT ownership for external listing","description":"Verify that the TXT ownership record has been added for an external domain listing. On success, the listing status changes from `pending_verification` to `active` and becomes buyable.\n\nRequires `deals:write` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":10,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","description":"Domain name to verify"}},"required":["domain"]}}}},"responses":{"200":{"description":"Listing verified and activated","content":{"application/json":{"schema":{"type":"object","properties":{"listing":{"type":"object"},"hint":{"type":"string"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"TXT record not found","code":"VERIFICATION_FAILED","hint":"Add the TXT record shown in the sell response to your DNS, then retry","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Listing not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Listing not found","code":"NOT_FOUND","hint":"Verify the listing exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/sell/status":{"get":{"operationId":"getSellStatus","summary":"Check listing and deal status","description":"Check the status of a domain listing and any active deal. Returns listing details, deal pipeline status, and contextual hints.\n\nRequires `deals:read` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string"},"description":"Domain name to check"}],"responses":{"200":{"description":"Listing and deal status","content":{"application/json":{"schema":{"type":"object","properties":{"listing":{"type":"object","nullable":true},"deal":{"type":"object","nullable":true},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Listing not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Listing not found","code":"NOT_FOUND","hint":"Verify the listing exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/deals":{"get":{"operationId":"listDeals","summary":"List your deals","description":"List marketplace deals where you are the buyer or seller. Filter by role or status.\n\nRequires `deals:read` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"role","in":"query","schema":{"type":"string","enum":["buyer","seller"]},"description":"Filter by role"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","escrow_held","epp_pending","transfer_started","completed","refunded","expired"]},"description":"Filter by status ('active' = all non-terminal)"},{"name":"domain","in":"query","schema":{"type":"string"},"description":"Filter by domain name"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Number of deals to return (default 50, max 100)"},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Cursor for pagination (deal ID from next_cursor)"}],"responses":{"200":{"description":"List of deals","content":{"application/json":{"schema":{"type":"object","properties":{"deals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"price":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string"},"role":{"type":"string","enum":["buyer","seller"]},"payment_method":{"type":"string"},"epp_deadline":{"type":"string","format":"date-time","nullable":true},"transfer_deadline":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}}},"has_more":{"type":"boolean","description":"Whether more results are available"},"next_cursor":{"type":"string","nullable":true,"description":"Cursor for the next page"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"post":{"operationId":"createDeal","summary":"Purchase an external domain (create deal)","description":"Create an escrow deal to purchase a domain listed on the marketplace. Buyer's payment is held in escrow until the domain transfer completes. The seller is notified and has 7 days to provide the EPP/auth code.\n\nRequires `domains:transfer` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":10,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","description":"Domain name to purchase"},"payment_method":{"type":"string","enum":["card","usdc","balance"],"description":"Payment method: 'card' (default), 'usdc', or 'balance' (marketplace credit)."}},"required":["domain"]}}}},"responses":{"201":{"description":"Deal created, payment in escrow","content":{"application/json":{"schema":{"type":"object","properties":{"deal":{"type":"object"},"hint":{"type":"string"},"next_steps":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"You cannot buy your own listing","code":"SELF_PURCHASE","hint":"You own this domain listing","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Listing not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Listing not found","code":"NOT_FOUND","hint":"Verify the listing exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/deals/{id}":{"get":{"operationId":"getDeal","summary":"Get deal detail with timeline","description":"Get full details of a deal including price breakdown, deadlines, and event timeline. Both buyer and seller can access their deals.\n\nRequires `deals:read` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Deal ID"}],"responses":{"200":{"description":"Deal details with event timeline","content":{"application/json":{"schema":{"type":"object","properties":{"deal":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"price":{"type":"number"},"currency":{"type":"string"},"fee":{"type":"number"},"seller_credit":{"type":"number"},"status":{"type":"string","enum":["escrow_held","epp_pending","transfer_started","completed","refunded","expired"]},"role":{"type":"string","enum":["buyer","seller"]},"payment_method":{"type":"string"},"epp_deadline":{"type":"string","format":"date-time","nullable":true},"transfer_deadline":{"type":"string","format":"date-time","nullable":true},"completed_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"events":{"type":"array","items":{"type":"object","properties":{"status":{"type":"string"},"detail":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}}}}},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Deal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Deal not found","code":"NOT_FOUND","hint":"Verify the deal exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"patch":{"operationId":"provideEppCode","summary":"Provide EPP/auth code (seller)","description":"Seller provides the EPP/authorization code to initiate the domain transfer. The code is encrypted at rest and used to start the registrar transfer. Max 3 attempts.\n\nRequires `deals:write` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":10,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Deal ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"auth_code":{"type":"string","description":"EPP/authorization code from the current registrar"}},"required":["auth_code"]}}}},"responses":{"200":{"description":"EPP code accepted, transfer initiated","content":{"application/json":{"schema":{"type":"object","properties":{"deal":{"type":"object"},"hint":{"type":"string"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Maximum EPP attempts exceeded","code":"EPP_ATTEMPTS_EXCEEDED","hint":"Contact support for assistance","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Deal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Deal not found","code":"NOT_FOUND","hint":"Verify the deal exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"409":{"description":"Invalid deal state for this operation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Deal is not in epp_pending state","code":"INVALID_DEAL_STATE","hint":"This deal is not awaiting an EPP code"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/deals/{id}/invoice":{"get":{"operationId":"getDealInvoice","summary":"Get a deal receipt / statement","description":"Returns a role-aware invoice for a marketplace deal. Buyers get a purchase receipt; sellers get a statement showing the sale, the platform commission line, and the net payout. Works for every payment method (card/USDC/balance). Requires `deals:read` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deal invoice","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"invoice":{"$ref":"#/components/schemas/DealInvoice"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/negotiations":{"get":{"operationId":"listNegotiations","summary":"List your negotiations","description":"Lists price negotiations where you are the buyer or seller. Counterparties are anonymized (roles only). Requires `deals:read` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"role","in":"query","schema":{"type":"string","enum":["buyer","seller"]},"description":"Filter by your role"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by status (open|agreed|completed|declined|expired|cancelled|all)"}],"responses":{"200":{"description":"Your negotiations","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"negotiations":{"type":"array","items":{"$ref":"#/components/schemas/Negotiation"}}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"post":{"operationId":"makeOffer","summary":"Make an offer on a listing","description":"Opens an anonymous price negotiation on an actively-listed domain with an initial offer. The seller can counter, accept, or decline. On acceptance the buyer finalizes payment and a deal is created at the agreed price. Requires `deals:write` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":30,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain","offer"],"properties":{"domain":{"type":"string","description":"The listed domain to negotiate on"},"offer":{"type":"number","description":"Initial offer in USD"},"message":{"type":"string","description":"Optional message to the seller"}}},"example":{"domain":"example.com","offer":500,"message":"Serious buyer, can close today."}}}},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/negotiations \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"domain\":\"example.com\",\"offer\":500}'"}],"responses":{"201":{"description":"Negotiation opened","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"negotiation":{"$ref":"#/components/schemas/Negotiation"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"No active listing for the domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/negotiations/{id}":{"get":{"operationId":"getNegotiation","summary":"Get a negotiation thread","description":"Returns a negotiation with its full offer thread, anonymized (offers are labelled 'you' or 'counterparty'). Requires `deals:read` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Negotiation","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"negotiation":{"$ref":"#/components/schemas/Negotiation"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"post":{"operationId":"respondToNegotiation","summary":"Counter, accept, or decline","description":"Respond to the current offer on the table when it's your turn. `counter` requires a new amount; `accept` locks the price at the amount currently on the table; `decline` ends the negotiation. Requires `deals:write` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["counter","accept","decline"]},"counter":{"type":"number","description":"New amount in USD (required when action=counter)"},"message":{"type":"string"}}},"example":{"action":"counter","counter":750}}}},"responses":{"200":{"description":"Updated negotiation","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"negotiation":{"$ref":"#/components/schemas/Negotiation"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"409":{"description":"State changed / not your turn","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"delete":{"operationId":"cancelNegotiation","summary":"Withdraw a negotiation","description":"Buyer withdraws an open or agreed negotiation. Requires `deals:write` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":20,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"cancelled":{"type":"boolean"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/negotiations/{id}/finalize":{"post":{"operationId":"finalizeNegotiation","summary":"Finalize an agreed negotiation (pay)","description":"Buyer pays the agreed price to create the escrow deal, then the standard transfer flow runs. Accepts the same payment methods as a marketplace purchase (card, USDC, x402). Returns 402 with payment instructions if no payment is provided. For a broker-sourced acquisition, if the agreed price is above the `max_budget` you set, returns 409 `BUDGET_EXCEEDED` - re-submit with `confirm_over_budget: true` to proceed. Requires `domains:transfer` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":20,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"payment_method":{"type":"string","enum":["card","usdc","balance"]},"payment_signature":{"type":"string","nullable":true},"payment_tx":{"type":"string"},"payment_chain":{"type":"string"},"confirm_over_budget":{"type":"boolean","description":"For broker deals: proceed even though the agreed price exceeds the max_budget you set."}}}}}},"responses":{"201":{"description":"Deal created at the agreed price","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Deal"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"402":{"description":"Payment required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not in agreed state, or `BUDGET_EXCEEDED` (agreed price above your max_budget - retry with confirm_over_budget)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/broker":{"get":{"operationId":"listBrokerRequests","summary":"List your broker requests","description":"Lists your domain acquisition requests and their status. Requires `deals:read` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by status or 'all'"}],"responses":{"200":{"description":"Your broker requests","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/BrokerRequest"}}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"post":{"operationId":"createBrokerRequest","summary":"Request acquisition of a taken domain","description":"Ask domani to acquire a specific taken, unlisted domain on your behalf. Agents source the owner via RDAP, reach out anonymously, and negotiate - commission-only, no upfront fee. Owner interest opens an anonymous negotiation. Note: many owners are unreachable (GDPR-redacted WHOIS) - the request then ends `no_contact`. Requires `deals:write` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":20,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","description":"The taken domain you want"},"max_budget":{"type":"number","description":"Your ceiling in USD (optional)"}}},"example":{"domain":"dream.com","max_budget":5000}}}},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/broker \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"domain\":\"dream.com\",\"max_budget\":5000}'"}],"responses":{"201":{"description":"Broker request created (status sourcing)","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"request":{"$ref":"#/components/schemas/BrokerRequest"}}}}}},"400":{"description":"Rejected: `ALREADY_LISTED`, `DOMAIN_AVAILABLE`, `REQUEST_EXISTS`, `DOMAIN_IN_BROKERAGE` (already being brokered for another buyer), `UNSUPPORTED_TLD` (registrar can't transfer this TLD), `RESTRICTED`, `INVALID_DOMAIN`, `INVALID_AMOUNT`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/broker/{id}":{"get":{"operationId":"getBrokerRequest","summary":"Get a broker request","description":"Returns one of your broker requests. Requires `deals:read` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Broker request","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"request":{"$ref":"#/components/schemas/BrokerRequest"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"delete":{"operationId":"cancelBrokerRequest","summary":"Cancel a broker request","description":"Cancels an active domain acquisition request. Requires `deals:write` scope.","tags":["Marketplace"],"x-rateLimit":{"limit":20,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"cancelled":{"type":"boolean"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/broker/respond":{"get":{"operationId":"getBrokerInquiryState","summary":"Read a broker inquiry's state (owner side)","description":"The owner-agent read path: poll the current, anonymized state of an inquiry with your `token` before acting. Returns the domain, the buyer's offer on the table, whose move it is, and the actions available now. Never exposes the buyer's identity or budget. Token-authorized.","tags":["Marketplace"],"security":[],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"The outreach token from your inquiry email."}],"responses":{"200":{"description":"Inquiry state","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string"},"your_turn":{"type":"boolean","description":"Whether it's the owner's move."},"current_offer_usd":{"type":"number","nullable":true,"description":"The buyer's offer on the table."},"agreed_price_usd":{"type":"number","nullable":true},"actions":{"type":"array","items":{"type":"string"},"description":"Actions available now (subset of offer/counter/accept/decline/opt_out)."}}}}}},"400":{"description":"Invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl \"https://domani.run/api/broker/respond?token=<from your inbox>\""}]},"post":{"operationId":"respondToBrokerInquiry","summary":"Respond to a broker inquiry (owner side)","description":"The owner-agent path: respond to a broker's acquisition inquiry using the `token` from the outreach email delivered to your inbox - the fully autonomous alternative to replying by email or clicking the human claim link. `offer`/`counter` open or advance an anonymous negotiation at your asking price; `decline` and `opt_out` end it. Token-authorized (the token is the capability) - no account or scope required.","tags":["Marketplace"],"security":[],"x-rateLimit":{"limit":20,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","action"],"properties":{"token":{"type":"string","description":"The outreach token from your inquiry email (the reply-to is broker+<token>@)."},"action":{"type":"string","enum":["offer","counter","accept","decline","opt_out"],"description":"offer/counter to name a price; accept to take the buyer's current offer on the table; decline to refuse; opt_out to never be contacted again."},"price":{"type":"number","description":"Your asking price in USD (required for offer/counter)."}}}}}},"responses":{"200":{"description":"Response applied","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"handled":{"type":"boolean"},"outcome":{"type":"string","description":"opted_out | declined | negotiation_opened | countered | ignored_not_your_turn | unclear"},"status":{"type":"string"},"negotiation_id":{"type":"string"},"domain":{"type":"string"}}}}}},"400":{"description":"Invalid token or missing price","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/broker/respond \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"token\":\"<from your inbox>\",\"action\":\"offer\",\"price\":800}'"}]}},"/api/notifications":{"get":{"operationId":"listNotifications","summary":"List notifications","description":"List your in-app notifications with cursor-based pagination. Includes deal events, listing updates, and system alerts.\n\nRequires `notifications:read` scope.","tags":["Notifications"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100},"description":"Max notifications to return"},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Cursor for pagination (from previous response's next_cursor)"}],"responses":{"200":{"description":"List of notifications","content":{"application/json":{"schema":{"type":"object","properties":{"notifications":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"action_url":{"type":"string","nullable":true},"read":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}}},"has_more":{"type":"boolean"},"next_cursor":{"type":"string","nullable":true}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/notifications/count":{"get":{"operationId":"getUnreadCount","summary":"Get unread notification count","description":"Lightweight endpoint for polling unread notification count.\n\nRequires `notifications:read` scope.","tags":["Notifications"],"x-rateLimit":{"limit":120,"window":"1 minute"},"responses":{"200":{"description":"Unread count","content":{"application/json":{"schema":{"type":"object","properties":{"unread_count":{"type":"integer"}}},"example":{"unread_count":3}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/notifications/{id}":{"patch":{"operationId":"markNotificationRead","summary":"Mark notification as read","description":"Mark a single notification as read.\n\nRequires `notifications:read` scope.","tags":["Notifications"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Notification ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"read":{"type":"boolean","description":"Set to true to mark as read"}},"required":["read"]}}}},"responses":{"200":{"description":"Notification updated","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Notification not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Notification not found","code":"NOT_FOUND","hint":"Verify the notification exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/notifications/read-all":{"post":{"operationId":"markAllNotificationsRead","summary":"Mark all notifications as read","description":"Mark all unread notifications as read.\n\nRequires `notifications:read` scope.","tags":["Notifications"],"x-rateLimit":{"limit":10,"window":"1 minute"},"responses":{"200":{"description":"All notifications marked as read","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"count":{"type":"integer","description":"Number of notifications marked as read"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/notifications/preferences":{"get":{"operationId":"getNotificationPreferences","summary":"Get notification preferences","description":"Returns the user's notification preferences for each category and channel (in_app, email). Missing preferences default to enabled.\n\nRequires `notifications:read` scope.","tags":["Notifications"],"x-rateLimit":{"limit":30,"window":"1 minute"},"responses":{"200":{"description":"Notification preferences","content":{"application/json":{"schema":{"type":"object","properties":{"preferences":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string","description":"Preference category","enum":["domains","transfers","marketplace","email","inquiries"]},"label":{"type":"string"},"description":{"type":"string"},"channel":{"type":"string","enum":["in_app","email"]},"enabled":{"type":"boolean"}}}},"expiry_alert_days":{"type":"array","items":{"type":"integer"},"example":[30,7,1],"description":"Days-before-expiry the user receives renewal reminders (default 30/7/1). Empty = no expiry reminders."}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"put":{"operationId":"updateNotificationPreferences","summary":"Update notification preferences","description":"Update notification preferences for specific categories and channels.\n\nRequires `notifications:read` scope.","tags":["Notifications"],"x-rateLimit":{"limit":10,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Provide `preferences` and/or `expiry_alert_days`.","properties":{"preferences":{"type":"array","items":{"type":"object","required":["category","channel","enabled"],"properties":{"category":{"type":"string","enum":["domains","transfers","marketplace","email","inquiries"]},"channel":{"type":"string","enum":["in_app","email"]},"enabled":{"type":"boolean"}}}},"expiry_alert_days":{"type":"array","items":{"type":"integer","minimum":1,"maximum":365},"example":[30,7,1],"description":"Days-before-expiry to receive renewal reminders. Empty array = no expiry reminders."}}}}}},"responses":{"200":{"description":"Preferences updated","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/analytics":{"get":{"operationId":"getParkingAnalytics","summary":"Get parking analytics","description":"Get visitor analytics for a parked domain - page views, inquiries, conversion rate, 30-day daily breakdown, and recent inquiries.","tags":["Domains"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"responses":{"200":{"description":"Parking analytics data","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"views_7d":{"type":"integer","description":"Total page views in the last 7 days"},"views_30d":{"type":"integer","description":"Total page views in the last 30 days"},"inquiries_30d":{"type":"integer","description":"Total inquiries in the last 30 days"},"conversion_rate":{"type":"number","description":"Inquiry-to-view ratio as percentage"},"daily_views":{"type":"array","description":"Daily view counts for the last 30 days","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"views":{"type":"integer"}}}},"recent_inquiries":{"type":"array","description":"5 most recent inquiries","items":{"type":"object","properties":{"email":{"type":"string"},"offer":{"type":"number","nullable":true},"date":{"type":"string","format":"date-time"}}}},"hint":{"type":"string"}}},"example":{"domain":"example.com","views_7d":42,"views_30d":156,"inquiries_30d":3,"conversion_rate":1.92,"daily_views":[{"date":"2026-02-25","views":7}],"recent_inquiries":[{"email":"buyer@example.com","offer":500,"date":"2026-02-25T10:00:00Z"}],"hint":"example.com received 156 views and 3 inquiries in the last 30 days (1.92% conversion)."}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/auth-code":{"get":{"operationId":"getAuthCode","summary":"Get EPP auth code","description":"Get the EPP/auth code needed to transfer a domain to another registrar. Automatically unlocks the domain if it's locked.","tags":["Domains"],"x-rateLimit":{"limit":10,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Auth code retrieved","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"auth_code":{"type":"string","description":"EPP auth code to give to the new registrar"},"was_unlocked":{"type":"boolean","description":"Whether the domain was auto-unlocked"},"hint":{"type":"string"},"next_steps":{"type":"array","items":{"type":"string"}}},"required":["domain","auth_code","was_unlocked","hint","next_steps"]},"examples":{"unlocked":{"summary":"Auth code with auto-unlock","value":{"domain":"mysite.com","auth_code":"aBc123XyZ","was_unlocked":true,"hint":"Auth code retrieved. Domain was automatically unlocked to allow transfer.","next_steps":["Give this auth code to your new registrar to initiate the transfer.","The transfer typically takes 5-7 days to complete.","Use get_transfer_away to monitor the transfer status."]}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/transfer-away":{"get":{"operationId":"getTransferAway","summary":"Get outbound transfer status","description":"Check the status of an outbound domain transfer. Use after getting an auth code and initiating the transfer at the new registrar.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Transfer status retrieved","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["none","pending","approved","completed","rejected","expired"]},"gaining_registrar":{"type":"string"},"request_date":{"type":"string","format":"date-time"},"hint":{"type":"string"}},"required":["domain","status","hint"]},"examples":{"none":{"summary":"No transfer in progress","value":{"domain":"mysite.com","status":"none","hint":"No outbound transfer in progress."}},"pending":{"summary":"Transfer pending","value":{"domain":"mysite.com","status":"pending","gaining_registrar":"Cloudflare","request_date":"2026-02-20T10:00:00Z","hint":"Transfer is pending approval. The gaining registrar has initiated the transfer."}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/transfer-status":{"get":{"operationId":"checkTransferStatus","summary":"Check inbound transfer status","description":"Check the status of an inbound domain transfer. Returns detailed status with actionable hints. Use after initiating a transfer with POST /api/domains/transfer.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"responses":{"200":{"description":"Transfer status retrieved","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["pending_owner","pending_admin","pending_registry","completed","cancelled","unknown"]},"timestamp":{"type":"string","description":"Timestamp of last status update"},"hint":{"type":"string","description":"Actionable guidance based on the current status"},"continuity":{"type":"object","description":"Captured delegation and post-transfer verification for safe transfers.","properties":{"strategy":{"type":"string","enum":["preserve_nameservers"]},"expected_nameservers":{"type":"array","items":{"type":"string"}},"dns_provider":{"type":"string"},"dnssec_enabled":{"type":"boolean"},"verification":{"type":"object","properties":{"status":{"type":"string","enum":["verified","repaired","degraded","unknown"]},"nameserversPreserved":{"type":"boolean","nullable":true},"dnssecPreserved":{"type":"boolean","nullable":true},"repairedNameservers":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"string"}}}}}}},"required":["domain","status","hint"]},"examples":{"pending_owner":{"summary":"Awaiting owner approval","value":{"domain":"mysite.com","status":"pending_owner","hint":"Transfer is awaiting approval from the domain owner (admin contact). Check email for confirmation link."}},"completed":{"summary":"Transfer completed","value":{"domain":"mysite.com","status":"completed","hint":"Transfer completed successfully. The domain is now in your account."}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/import":{"post":{"operationId":"importDomain","summary":"Import an external domain","description":"Import a domain you own at another registrar (GoDaddy, Namecheap, Cloudflare, etc.) to manage through domani.run. Free, no transfer needed. Returns a TXT record for DNS-based ownership verification.","tags":["Domains"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","example":"mysite.com","description":"Domain to import"}}}}}},"responses":{"200":{"description":"Verification instructions","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","example":"pending_verification"},"token":{"type":"string"},"txt_record":{"type":"object","properties":{"type":{"type":"string","example":"TXT"},"name":{"type":"string","example":"@"},"value":{"type":"string","example":"domani-verify=abc123..."}}},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"409":{"description":"Domain already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain already registered in our system","code":"DOMAIN_EXISTS","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/import/verify":{"post":{"operationId":"verifyImport","summary":"Verify and complete domain import","description":"Verify DNS TXT record and complete domain import. Call after adding the TXT record returned by POST /api/domains/import. Uses Cloudflare DNS-over-HTTPS to check propagation.","tags":["Domains"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","example":"mysite.com","description":"Domain to verify"}}}}}},"responses":{"201":{"description":"Domain imported successfully","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","example":"active"},"expires":{"type":"string","format":"date-time"},"registrar":{"type":"string","example":"external"},"payment_method":{"type":"string","example":"import"},"hint":{"type":"string"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"TXT record not found","code":"VERIFICATION_FAILED","hint":"Add TXT record and wait for DNS propagation","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"409":{"description":"Domain already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain already registered in our system","code":"DOMAIN_EXISTS","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/adoption-plan":{"get":{"operationId":"planDomainAdoption","summary":"Plan how to adopt an existing domain","description":"Read-only inspection of an existing domain before connecting or transferring it. Returns the current registrar, authoritative nameservers, DNS provider, DNSSEC state, account state, transfer price, safety invariants, and exact next API actions. Call this before requesting an EPP code. Connecting leaves registrar and DNS unchanged. Transferring preserves nameservers and does not migrate DNS.","tags":["Domains"],"security":[{"bearerAuth":[]}],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string"},"description":"Existing domain to inspect, e.g. mysite.com"}],"responses":{"200":{"description":"Versioned domain adoption plan","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","required":["version","domain","registered","account_state","recommended_action","current","options","invariants","warnings"],"properties":{"version":{"type":"integer","enum":[1]},"domain":{"type":"string"},"registered":{"type":"boolean"},"account_state":{"type":"string","enum":["untracked","connected","managed","owned_by_another"]},"recommended_action":{"type":"string","enum":["acquire","connect","transfer_preserving_dns","none"]},"current":{"type":"object","required":["registrar","registrar_url","expires_at","status","nameservers","dns_provider","dnssec_enabled"],"properties":{"registrar":{"type":"string","nullable":true},"registrar_url":{"type":"string","nullable":true},"expires_at":{"type":"string","format":"date-time","nullable":true},"status":{"type":"array","items":{"type":"string"}},"nameservers":{"type":"array","items":{"type":"string"}},"dns_provider":{"type":"string","example":"cloudflare"},"dnssec_enabled":{"type":"boolean"}}},"options":{"type":"object","properties":{"connect":{"type":"object","properties":{"available":{"type":"boolean"},"price":{"type":"number","enum":[0]},"currency":{"type":"string"},"changes_registrar":{"type":"boolean","enum":[false]},"changes_nameservers":{"type":"boolean","enum":[false]},"next_action":{"type":"object","properties":{"method":{"type":"string"},"path":{"type":"string"}}}}},"transfer":{"type":"object","properties":{"available":{"type":"boolean"},"eligible":{"type":"boolean"},"price":{"type":"number","nullable":true},"currency":{"type":"string"},"includes_renewal":{"type":"boolean","enum":[true]},"preserves_nameservers":{"type":"boolean","enum":[true]},"migrates_dns":{"type":"boolean","enum":[false]},"reason":{"type":"string"},"code":{"type":"string"},"eligible_at":{"type":"string","format":"date"},"next_action":{"type":"object","properties":{"method":{"type":"string"},"path":{"type":"string"}}}}}}},"invariants":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"domain query parameter is required","code":"INVALID_PARAMETER","hint":"Pass ?domain=example.com","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/transfer-check":{"get":{"operationId":"checkTransferEligibility","summary":"Pre-check transfer eligibility","description":"Check whether a domain is eligible for transfer before initiating. Returns transfer price, eligibility status, and any blockers (unsupported TLD, ICANN waiting period, domain locked). Call this before POST /api/domains/transfer.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string"},"description":"Domain to check, e.g. mysite.com"}],"responses":{"200":{"description":"Eligibility check result","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"tld":{"type":"string"},"eligible":{"type":"boolean"},"price":{"type":"number","nullable":true,"description":"Transfer price in USD (null if TLD unsupported)"},"currency":{"type":"string"},"reason":{"type":"string","description":"Human-readable reason if not eligible"},"code":{"type":"string","enum":["UNSUPPORTED_TLD","NOT_AVAILABLE","ALREADY_REGISTERED","TRANSFER_NOT_ELIGIBLE"]},"eligible_at":{"type":"string","format":"date","description":"ISO date when domain becomes eligible (ICANN waiting period)"},"hint":{"type":"string"}},"required":["domain","tld","eligible","price","currency"]},"examples":{"eligible":{"summary":"Domain is eligible","value":{"domain":"mysite.com","tld":"com","eligible":true,"price":13.08,"currency":"USD","hint":"Transfer includes 1 year of renewal. Price: $13.08 USD."}},"unsupported":{"summary":"TLD not supported","value":{"domain":"mysite.so","tld":"so","eligible":false,"price":null,"currency":"USD","reason":"TLD .so is not available for transfer.","code":"UNSUPPORTED_TLD","hint":"Use GET /api/tlds to see supported TLDs."}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"domain query parameter is required","code":"INVALID_PARAMETER","hint":"Pass ?domain=example.com","documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/transfer-watch":{"post":{"operationId":"watchTransfer","summary":"Watch a domain for transfer eligibility","description":"Watch a domain and get notified (email + transfer.eligible webhook) when it becomes eligible for transfer. Uses RDAP to check EPP status codes and ICANN 60-day lock windows. If already eligible, returns immediately without creating a watch.","tags":["Domains"],"x-rateLimit":{"limit":30,"window":"1 minute"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","description":"Domain to watch, e.g. mysite.com"}}},"examples":{"watch":{"summary":"Watch a domain","value":{"domain":"mysite.com"}}}}}},"responses":{"200":{"description":"Watch result","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"eligible":{"type":"boolean","description":"Whether the domain is currently eligible for transfer"},"eligible_at":{"type":"string","format":"date","description":"ISO date when domain becomes eligible (if not yet eligible)"},"hint":{"type":"string","description":"Actionable guidance"},"watching":{"type":"boolean","description":"Whether a notification has been set up"}},"required":["domain","eligible","watching"]},"examples":{"watching":{"summary":"Domain not yet eligible, watching","value":{"domain":"mysite.com","eligible":false,"eligible_at":"2026-04-16","hint":"Domain was registered on 2026-02-15. ICANN requires a 60-day wait. Transferable from 2026-04-16. We'll notify you (email + webhook) when it's ready.","watching":true}},"alreadyEligible":{"summary":"Domain already eligible","value":{"domain":"mysite.com","eligible":true,"hint":"Domain is already eligible for transfer. You can initiate a transfer now with POST /api/domains/transfer.","watching":false}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"domain is required","code":"INVALID_PARAMETER","hint":"Send { \"domain\": \"example.com\" }","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/transfer":{"post":{"operationId":"transferDomain","summary":"Transfer domain from another provider","description":"Initiate a domain transfer-in after planDomainAdoption and explicit price confirmation. Requires the authorization/EPP code from the current provider. The existing authoritative nameservers are preserved and verified. DNS migration is never implicit. Transfer typically takes 1-5 days to complete. Payment is charged upfront via card or USDC.","tags":["Domains"],"x-rateLimit":{"limit":5,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/domains/transfer \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"domain\": \"mysite.com\", \"auth_code\": \"EPP-AUTH-CODE\"}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["domain","auth_code"],"properties":{"domain":{"type":"string","description":"Domain to transfer, e.g. mysite.com"},"auth_code":{"type":"string","description":"Authorization/EPP code from the current provider"},"payment_method":{"type":"string","enum":["card","usdc","balance"],"description":"Payment method: 'card' (default), 'usdc', or 'balance' (marketplace credit)."},"payment_tx":{"type":"string","description":"Transaction hash of a USDC payment already sent on-chain."},"payment_chain":{"type":"string","enum":["base","ethereum"],"description":"Chain the USDC payment was sent on."},"extra_subdomains":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Additional subdomains to include in the pre-transfer DNS snapshot. We auto-discover subdomains via CT logs, SPF, MX/DKIM inference, and a common wordlist - use this for any custom subdomains we might miss."}}},"examples":{"transfer":{"summary":"Transfer a domain","value":{"domain":"mysite.com","auth_code":"aBc123XyZ"}}}}}},"responses":{"202":{"description":"Transfer initiated","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["pending","active"]},"expires":{"type":"string","format":"date-time"},"price":{"type":"number"},"currency":{"type":"string"},"payment_method":{"type":"string"},"payment_tx":{"type":"string"},"auto_renew":{"type":"boolean"},"hint":{"type":"string"},"dns_snapshot":{"type":"object","description":"Recovery backup summary captured before transfer. It is not applied unless an explicit recovery operation is needed.","properties":{"record_count":{"type":"integer","description":"Total DNS records captured"},"subdomain_count":{"type":"integer","description":"Number of subdomains discovered"}}},"nameservers_preserved":{"type":"boolean","enum":[true]},"dns_migration":{"type":"string","enum":["not_requested"]},"continuity":{"type":"object","properties":{"nameservers":{"type":"array","items":{"type":"string"}},"dns_provider":{"type":"string"},"dnssec_enabled":{"type":"boolean"},"verification_status":{"type":"string","enum":["verified","repaired","degraded","unknown"]}}}},"required":["domain","status","expires","price","currency","payment_method","hint","nameservers_preserved","dns_migration","continuity"]},"examples":{"pending":{"summary":"Transfer pending","value":{"domain":"mysite.com","status":"pending","expires":"2027-02-18T00:00:00.000Z","price":13.99,"currency":"USD","payment_method":"card","hint":"Transfer initiated. It may take up to 5 days to complete. Check status with GET /api/domains/{domain}"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Valid domain and auth_code are required","code":"INVALID_DOMAIN","hint":"Provide domain and auth_code in the request body","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"402":{"description":"Payment required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Payment required","code":"PAYMENT_REQUIRED","hint":"Add a card via POST /api/billing/setup, or pay with USDC on Base (x402)","documentation_url":"https://domani.run/llms.txt"}}}},"409":{"description":"Domain already registered in our system","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain already registered in our system","code":"DOMAIN_EXISTS","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/renew":{"post":{"operationId":"renewDomain","summary":"Renew a domain","description":"Renew a domain you own for additional years (1-10). Payment is charged upfront. The new expiry date is returned in the response.","tags":["Domains"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL - Renew 1 year","source":"curl -X POST https://domani.run/api/domains/mysite.com/renew \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"years\": 1}'"},{"lang":"bash","label":"cURL - Renew 3 years","source":"curl -X POST https://domani.run/api/domains/mysite.com/renew \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"years\": 3}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"mysite.com"},"description":"Domain name you own"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"years":{"type":"integer","minimum":1,"maximum":10,"default":1,"description":"Number of years to renew (default 1)"},"payment_method":{"type":"string","enum":["card","usdc","balance"],"description":"Payment method: 'card' (default), 'usdc', or 'balance' (marketplace credit)."},"payment_tx":{"type":"string","description":"Transaction hash of a USDC payment already sent on-chain."},"payment_chain":{"type":"string","enum":["base","ethereum"],"description":"Chain the USDC payment was sent on."},"max_price":{"type":"number","example":20,"description":"Ceiling in USD for the renewal charge. If the real price exceeds it, the request fails with 400 PRICE_ABOVE_MAX and nothing is charged."}}},"examples":{"one_year":{"summary":"Renew 1 year","value":{"years":1}},"three_years":{"summary":"Renew 3 years","value":{"years":3}}}}}},"responses":{"200":{"description":"Domain renewed","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"renewed_years":{"type":"integer"},"new_expiry":{"type":"string","format":"date-time"},"price":{"type":"number"},"currency":{"type":"string"},"payment_method":{"type":"string"},"payment_tx":{"type":"string"}},"required":["domain","renewed_years","new_expiry","price","currency","payment_method"]},"examples":{"renewed":{"summary":"Domain renewed for 2 years","value":{"domain":"mysite.com","renewed_years":2,"new_expiry":"2029-02-18T00:00:00.000Z","price":27.98,"currency":"USD","payment_method":"card"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"years must be an integer between 1 and 10","code":"INVALID_PARAMETER","hint":"Send { \"years\": 1 } (default) up to { \"years\": 10 }","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"402":{"description":"Payment required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Payment required","code":"PAYMENT_REQUIRED","hint":"Add a card via POST /api/billing/setup, or pay with USDC on Base (x402)","documentation_url":"https://domani.run/llms.txt"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/buy-aftermarket":{"post":{"operationId":"buyAftermarket","summary":"Buy an aftermarket domain","description":"Buy a taken domain that's listed for sale on an aftermarket (Afternic / Sedo) at its buy-now price, through Domani. The listing price is re-checked live before charging; pass `max_price` to cap what you'll pay. Make-offer-only listings can't be bought here - use the broker (`POST /api/broker`) to negotiate a price instead. Payment works like a registration: card, USDC on Base (x402), or marketplace balance. Requires the `domains:transfer` scope. On success the domain lands in your account (`status: active`, or `provisioning` while a staged transfer finalizes).","tags":["Domains"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL - buy at the listed price","source":"curl -X POST https://domani.run/api/domains/coolname.com/buy-aftermarket \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{}'"},{"lang":"bash","label":"cURL - cap the price","source":"curl -X POST https://domani.run/api/domains/coolname.com/buy-aftermarket \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"max_price\": 750}'"}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"coolname.com"},"description":"The aftermarket-listed domain to buy"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"max_price":{"type":"number","description":"Hard price ceiling in USD. Defaults to the listing's buy-now price; the purchase is rejected if the live price exceeds this."},"payment_method":{"type":"string","enum":["card","usdc","balance"],"description":"Payment method: 'card' (default), 'usdc', or 'balance' (marketplace credit)."},"payment_tx":{"type":"string","description":"Transaction hash of a USDC payment already sent on-chain."},"payment_chain":{"type":"string","enum":["base","ethereum"],"description":"Chain the USDC payment was sent on."}}},"examples":{"at_listed_price":{"summary":"Buy at the listed price","value":{}},"capped":{"summary":"Cap the price at $750","value":{"max_price":750}}}}}},"responses":{"201":{"description":"Domain purchased","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","description":"'active' when the purchase completed, or 'provisioning' while a staged transfer finalizes."},"price":{"type":"number"},"currency":{"type":"string"},"payment_method":{"type":"string"},"payment_tx":{"type":"string"},"marketplace":{"type":"string","description":"Aftermarket the domain was bought on (e.g. 'Afternic', 'Sedo')."},"hint":{"type":"string"},"next_steps":{"type":"array","items":{"type":"string"}}},"required":["domain","status","price","currency","payment_method","marketplace"]},"examples":{"bought":{"summary":"Bought on Afternic","value":{"domain":"coolname.com","status":"active","price":750,"currency":"USD","payment_method":"card","marketplace":"Afternic","hint":"coolname.com is yours - bought on Afternic for $750. Connect it to a host or email provider next.","next_steps":["Use connect_domain to point it to a hosting provider (Vercel, Netlify, ...).","Use set_dns to configure custom DNS records."]}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"This domain isn't listed for sale on a supported aftermarket, or it's make-offer only","code":"NOT_LISTED","hint":"Use the broker (POST /api/broker) to negotiate a make-offer listing.","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"402":{"description":"Payment required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Payment required","code":"PAYMENT_REQUIRED","hint":"Add a card via POST /api/billing/setup, or pay with USDC on Base (x402)","documentation_url":"https://domani.run/llms.txt"}}}},"404":{"description":"Domain not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Domain not found","code":"NOT_FOUND","hint":"Verify the domain exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/whois":{"get":{"operationId":"whoisLookup","summary":"Look up domain registration data via RDAP","description":"Queries the RDAP (Registration Data Access Protocol) network for domain registration data. Returns registrar, creation/expiry/update dates, days until expiry, status codes, nameservers, DNSSEC status, and contact information (registrant, admin, tech, billing, abuse). Works for any domain - no ownership required.\n\nRDAP is the modern, JSON-native replacement for WHOIS. Falls back to WHOIS (port 43) for TLDs without RDAP, and supplements RDAP with WHOIS referral data when contacts are missing (common post-GDPR). Contact information may be partially or fully redacted due to GDPR or privacy protection services. **Public endpoint** - no authentication required. Authenticated requests get higher rate limits (30/min vs 10/min).","tags":["Discovery"],"security":[],"x-rateLimit":{"limit":10,"window":"1 minute","scope":"IP address (unauthenticated), 30/min per user (authenticated)"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl \"https://domani.run/api/domains/whois?q=google.com\""}],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","example":"google.com"},"description":"Domain to look up (e.g. example.com)"}],"responses":{"200":{"description":"Domain registration data","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","example":"google.com"},"registered":{"type":"boolean","description":"Whether the domain is currently registered"},"registrar":{"type":"string","nullable":true,"example":"MarkMonitor Inc.","description":"Current registrar name"},"registrar_url":{"type":"string","nullable":true,"description":"Registrar website URL"},"registrar_iana_id":{"type":"string","nullable":true,"description":"Registrar IANA ID (from RDAP publicIds)"},"created":{"type":"string","nullable":true,"example":"1997-09-15","description":"Registration date (YYYY-MM-DD)"},"expires":{"type":"string","nullable":true,"example":"2028-09-14","description":"Expiration date (YYYY-MM-DD)"},"updated":{"type":"string","nullable":true,"example":"2019-09-09","description":"Last updated date (YYYY-MM-DD)"},"days_until_expiry":{"type":"integer","nullable":true,"example":939,"description":"Days until expiry (null if not registered)"},"status":{"type":"array","items":{"type":"string"},"example":["clientdeleteprohibited","clienttransferprohibited","clientupdateprohibited"],"description":"EPP status codes"},"nameservers":{"type":"array","items":{"type":"string"},"example":["ns1.google.com","ns2.google.com"],"description":"Authoritative nameservers"},"dnssec":{"type":"boolean","description":"Whether DNSSEC is enabled"},"redacted":{"type":"boolean","description":"Whether WHOIS/RDAP data is redacted for privacy (GDPR)"},"contacts":{"type":"object","description":"Contact information by role (null when no data available, fields may be null when redacted)","properties":{"registrant":{"oneOf":[{"$ref":"#/components/schemas/Contact"},{"type":"null"}],"description":"Domain owner/registrant"},"admin":{"oneOf":[{"$ref":"#/components/schemas/Contact"},{"type":"null"}],"description":"Administrative contact"},"tech":{"oneOf":[{"$ref":"#/components/schemas/Contact"},{"type":"null"}],"description":"Technical contact"},"billing":{"oneOf":[{"$ref":"#/components/schemas/Contact"},{"type":"null"}],"description":"Billing contact"},"abuse":{"oneOf":[{"$ref":"#/components/schemas/Contact"},{"type":"null"}],"description":"Abuse contact (email + phone)"}},"required":["registrant","admin","tech","billing","abuse"]}},"required":["domain","registered","registrar","registrar_url","registrar_iana_id","created","expires","updated","days_until_expiry","status","nameservers","dnssec","redacted","contacts"]},"examples":{"registered":{"summary":"Registered domain","value":{"domain":"google.com","registered":true,"registrar":"MarkMonitor Inc.","registrar_url":"http://www.markmonitor.com","registrar_iana_id":"292","created":"1997-09-15","expires":"2028-09-14","updated":"2019-09-09","days_until_expiry":939,"status":["clientdeleteprohibited","clienttransferprohibited","clientupdateprohibited","serverdeleteprohibited","servertransferprohibited","serverupdateprohibited"],"nameservers":["ns1.google.com","ns2.google.com","ns3.google.com","ns4.google.com"],"dnssec":false,"redacted":true,"contacts":{"registrant":{"name":"REDACTED FOR PRIVACY","organization":"Google LLC","email":"REDACTED FOR PRIVACY","phone":"REDACTED FOR PRIVACY","fax":null,"street":"REDACTED FOR PRIVACY","city":"REDACTED FOR PRIVACY","state":"CA","postal_code":"REDACTED FOR PRIVACY","country":"US"},"admin":null,"tech":null,"billing":null,"abuse":{"name":null,"organization":null,"email":"abusecomplaints@markmonitor.com","phone":"+1.2086851750","fax":null,"street":null,"city":null,"state":null,"postal_code":null,"country":null}}}},"unregistered":{"summary":"Unregistered domain","value":{"domain":"this-domain-is-not-registered.com","registered":false,"registrar":null,"registrar_url":null,"registrar_iana_id":null,"created":null,"expires":null,"updated":null,"days_until_expiry":null,"status":[],"nameservers":[],"dnssec":false,"redacted":false,"contacts":{"registrant":null,"admin":null,"tech":null,"billing":null,"abuse":null}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Invalid domain format","code":"INVALID_DOMAIN","hint":"Domain must be like example.com","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/domains/{domain}/og":{"get":{"operationId":"getDomainOg","summary":"Get website preview metadata for a domain","description":"Returns Open Graph metadata (title, description, image, favicon) for a domain. Data is lazily fetched and cached for 7 days. First request for a domain may take 1-5s (live fetch); subsequent requests are instant (cache hit). Returns null fields if the site is unreachable or has no OG tags.\n\n**Public endpoint** - no authentication required.","tags":["Discovery"],"security":[],"x-rateLimit":{"limit":30,"window":"1 minute","scope":"IP address"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl \"https://domani.run/api/domains/google.com/og\""}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","example":"google.com"},"description":"Domain to fetch metadata for (e.g. google.com)"}],"responses":{"200":{"description":"OG metadata","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","nullable":true,"example":"Google","description":"Page title (og:title > twitter:title > <title>)"},"description":{"type":"string","nullable":true,"example":"Search the world's information","description":"Page description (og:description > meta description)"},"image":{"type":"string","nullable":true,"description":"OG image URL (absolute)"},"favicon":{"type":"string","nullable":true,"example":"https://google.com/favicon.ico","description":"Favicon URL (absolute)"}},"required":["title","description","image","favicon"]}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Invalid domain format","code":"INVALID_DOMAIN","hint":"Domain must include a TLD","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/domains/dns-check":{"get":{"operationId":"dnsCheck","summary":"Fast DNS-based domain existence check","description":"Tests if a domain name is taken across many TLDs at once using DNS queries (faster than search, no pricing). Returns 'taken' (definitely registered) and 'candidates' (potentially available) arrays. Use this to narrow down before calling search for pricing. **Public endpoint** - no authentication required.","tags":["Domain Search"],"security":[],"x-rateLimit":{"limit":30,"window":"1 minute","scope":"IP address"},"parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string"},"description":"Domain name without TLD, e.g. 'myapp'"},{"name":"tlds","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated TLDs to check, e.g. 'com,dev,ai,io'"}],"responses":{"200":{"description":"DNS check results","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"taken":{"type":"array","items":{"type":"string"},"description":"TLDs that are definitely registered"},"candidates":{"type":"array","items":{"type":"string"},"description":"TLDs that are potentially available"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Query parameter 'name' is required","code":"MISSING_PARAMETER","hint":"Provide both 'name' and 'tlds' query parameters","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/tokens":{"get":{"operationId":"listTokens","summary":"List your API tokens","description":"Returns all API tokens for the authenticated user. Keys are masked for security (first 12 + last 4 characters visible). Use this to audit active tokens.","tags":["API Tokens"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/tokens \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"List of API tokens","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"tokens":{"type":"array","items":{"$ref":"#/components/schemas/TokenInfo"}}}},"example":{"tokens":[{"id":"cm5abc123","name":"Default","key":"domani_sk_a...wxyz","lastUsed":"2025-02-18T10:30:00.000Z","expiresAt":null,"expired":false,"scopes":["*"],"createdAt":"2025-01-15T10:30:00.000Z","max_per_tx":null,"max_per_month":null,"spent_this_month":0,"parent_token_id":null,"agent_identity":null},{"id":"cm5def456","name":"CI/CD","key":"domani_sk_b...vwxy","lastUsed":null,"expiresAt":"2025-05-01T14:00:00.000Z","expired":false,"scopes":["domains:read","domains:write"],"createdAt":"2025-02-01T14:00:00.000Z"}]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"post":{"operationId":"createToken","summary":"Create a new API token","description":"Creates a new API token. The full key is returned only in this response - store it securely. You can create multiple tokens to separate access for different applications.","tags":["API Tokens"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/tokens \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"CI/CD Pipeline\"}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"CI/CD Pipeline","description":"Human-readable name to identify this token"},"expires_in":{"type":"integer","example":2592000,"description":"Token lifetime in seconds (min 3600 = 1h, max 31536000 = 1y). Omit for no expiration."},"expires_at":{"type":"string","format":"date-time","description":"Absolute expiration date (ISO 8601). Alternative to expires_in."},"scopes":{"type":"array","items":{"type":"string"},"description":"Permission scopes for this token. Use ['*'] for full access (default). A token can only grant scopes it already has (scope attenuation). Scopes: domains:read (GET /api/domains, GET /api/domains/{domain}, GET /api/domains/{domain}/dns, /dnssec, /status, /email/check, /auth-code, /transfer-away, /transfer-status, /analytics), domains:write (PUT /api/domains/{domain}/dns, POST/DELETE /api/domains/{domain}/dnssec, POST /connect, POST /verify, PUT /settings, PUT /parking, PUT/DELETE /api/domains/{domain}/for-sale, POST /api/domains/import, POST /import/verify), domains:transfer (POST /api/domains/buy, POST /transfer, POST /renew (involves payment, includes marketplace purchases)), tokens:read (GET /api/tokens), tokens:write (POST /api/tokens, DELETE /api/tokens/{id}), webhooks:read (GET /api/webhooks, GET /api/webhooks/{id}/deliveries), webhooks:write (POST /api/webhooks, PATCH /api/webhooks/{id}, DELETE /api/webhooks/{id}), email:read (GET /api/emails, /api/emails/{address}, /api/emails/{address}/messages, /api/emails/{address}/aliases, /api/domains/{domain}/email/status, /api/domains/{domain}/email/deliverability, /api/suppressions), email:write (POST /api/emails, POST /api/emails/{address}/send, POST /api/domains/{domain}/email/setup, aliases + catch-all, POST/DELETE /api/suppressions), email:delete (Permanently delete messages already in Trash. Moving messages to Trash only requires email:write. Grant this scope only to agents allowed to irreversibly erase email content), email:auth_secrets (Read messages classified as authentication mail (OTP / verification codes, password resets, magic links). Without it, email:read still lists them but subject and body come back redacted - so a stolen agent token can't harvest 2FA codes. Grant it only to agents that genuinely need to complete logins), account:read (GET /api/me, GET /api/agents/identity), account:write (DELETE /api/me, POST /api/billing/setup, POST /api/billing/subscribe, POST /api/billing/cancel, POST /api/me/resend-verification, POST/PATCH/DELETE /api/agents/identity), billing:read (GET /api/billing/invoices), search (GET /api/domains/search, /suggest, /whois, /dns-check, GET /api/tlds), deals:read (GET /api/deals, GET /api/deals/{id}), deals:write (POST /api/domains/sell, PATCH /api/deals/{id}), notifications:read (GET /api/notifications, GET /api/notifications/count), backorders:read (GET /api/backorders, GET /api/backorders/{id}), backorders:write (POST /api/backorders, DELETE /api/backorders/{id})."},"max_per_tx":{"type":"number","example":25,"description":"Per-transaction spend cap in USD. Any single charge above this fails with 403 SPEND_CAP_EXCEEDED. A token can only grant caps at or below its own (CAP_ESCALATION otherwise)."},"max_per_month":{"type":"number","example":100,"description":"Rolling calendar-month spend cap in USD across all paid operations made with this token."},"agent_identity_id":{"type":"string","description":"Optional id of an agent identity owned by this account. Mail actions made with the token are attributed to that agent."}}},"example":{"name":"CI/CD Pipeline","expires_in":2592000,"scopes":["domains:read","domains:write"],"max_per_tx":25,"max_per_month":100}}}},"responses":{"201":{"description":"Token created - save the key, it won't be shown again","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"key":{"type":"string","description":"Full API key - save this, it won't be shown again"},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"When this token expires (null = never)"},"scopes":{"type":"array","items":{"type":"string"},"description":"Permission scopes granted to this token"},"createdAt":{"type":"string","format":"date-time"},"max_per_tx":{"type":"number","nullable":true,"description":"Per-transaction spend cap in USD (null = uncapped)"},"max_per_month":{"type":"number","nullable":true,"description":"Monthly spend cap in USD (null = uncapped)"},"agent_identity":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"slug":{"type":"string"}}}}},"example":{"id":"cm5ghi789","name":"CI/CD Pipeline","key":"domani_sk_x1Y2z3A4b5C6d7E8f9G0hIjK","expiresAt":"2025-03-20T10:30:00.000Z","scopes":["domains:read","domains:write"],"createdAt":"2025-02-18T10:30:00.000Z","max_per_tx":25,"max_per_month":100}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"403":{"description":"Token lacks required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Token does not have the required scope for this action","code":"INSUFFICIENT_SCOPE","hint":"Required scope: tokens:write. Create a new token with the needed scopes.","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/tokens/{id}":{"delete":{"operationId":"revokeToken","summary":"Revoke an API token","description":"Permanently revokes an API token. Any applications using this token will immediately lose access. This action cannot be undone.","tags":["API Tokens"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X DELETE https://domani.run/api/tokens/cm5abc123 \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"cm5abc123"},"description":"Token ID (from GET /api/tokens response)"}],"responses":{"200":{"description":"Token revoked successfully","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}},"example":{"success":true}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Token not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Token not found","code":"NOT_FOUND","hint":"Verify the token exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/audit":{"get":{"operationId":"listAuditEvents","summary":"List security audit events","description":"Returns the account's security audit trail, newest first: token lifecycle (created, revoked, escalation attempts), spend-cap and max_price denials, charges, payout requests, and blocked account deletions. Use it to monitor what your agents' tokens are doing.","tags":["API Tokens"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl \"https://domani.run/api/audit?limit=50\" \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Events per page"},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Pagination cursor (next_cursor from the previous page)"},{"name":"type","in":"query","required":false,"schema":{"type":"string","example":"purchase.denied_cap"},"description":"Filter by event type (e.g. token.created, purchase.charged, purchase.denied_cap)"}],"responses":{"200":{"description":"Audit events (newest first)","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"tokenId":{"type":"string","nullable":true,"description":"Token that performed the action (null = dashboard/session)"},"type":{"type":"string","example":"purchase.charged"},"targetType":{"type":"string","nullable":true},"targetId":{"type":"string","nullable":true},"metadata":{"type":"object"},"createdAt":{"type":"string","format":"date-time"}}}},"next_cursor":{"type":"string","nullable":true},"hint":{"type":"string"}}},"example":{"events":[{"id":"evt1","tokenId":"cm5abc123","type":"purchase.charged","targetType":"domain","targetId":"mysite.com","metadata":{"amountCents":1450,"operation":"buy","method":"card"},"createdAt":"2026-07-11T10:00:00.000Z"},{"id":"evt2","tokenId":"cm5abc123","type":"purchase.denied_cap","targetType":"domain","targetId":"expensive.ai","metadata":{"amountCents":8470},"createdAt":"2026-07-11T09:58:00.000Z"}],"next_cursor":null,"hint":"Security-relevant events for this account."}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/billing/setup":{"post":{"operationId":"setupBilling","summary":"Get checkout URL for adding a payment method","description":"Creates a checkout session for adding a credit card. Redirect the user to the returned URL. This is required before purchasing domains. After the user completes checkout, they are redirected back to the dashboard.","tags":["Billing"],"x-rateLimit":{"limit":60,"window":"1 minute"},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["setup_intent","checkout"],"default":"setup_intent","description":"setup_intent returns a client_secret for frontend Stripe.js. checkout returns a URL to redirect the user to Stripe Checkout."}}}}}},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/billing/setup \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"mode\": \"checkout\"}'"}],"responses":{"200":{"description":"Checkout URL or client secret depending on mode","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Checkout URL (checkout mode)"},"client_secret":{"type":"string","description":"Stripe SetupIntent client secret (setup_intent mode)"},"hint":{"type":"string","description":"Next steps guidance"}}},"example":{"url":"https://checkout.domani.run/session/cs_abc123...","hint":"Open this URL in a browser to add your payment card."}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/billing/card":{"delete":{"operationId":"removeCard","summary":"Remove saved payment method","description":"Detaches the user's saved credit card from their account. After removal, a new card must be added before purchasing domains.","tags":["Billing"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X DELETE https://domani.run/api/billing/card \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"Card removed","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"removed":{"type":"boolean"}}},"example":{"removed":true}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/billing/connect":{"get":{"operationId":"getPayoutStatus","summary":"Get marketplace payout status","description":"Returns the seller's Stripe Connect onboarding status and available marketplace balance. `payouts_enabled` is true once onboarding is complete and the seller can receive bank payouts.","tags":["Billing"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/billing/connect \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"Payout status","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"onboarded":{"type":"boolean","description":"Seller has submitted Connect onboarding details"},"payouts_enabled":{"type":"boolean","description":"Bank payouts are active"},"details_submitted":{"type":"boolean"},"balance_cents":{"type":"integer","description":"Available marketplace balance in cents"}}},"example":{"onboarded":true,"payouts_enabled":true,"details_submitted":true,"balance_cents":45000}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"post":{"operationId":"startPayoutOnboarding","summary":"Start bank payout onboarding","description":"Creates (or resumes) Stripe Connect Express onboarding for a marketplace seller and returns a hosted onboarding URL to redirect the user to. Required before a seller can withdraw earnings to their bank.","tags":["Billing"],"x-rateLimit":{"limit":20,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/billing/connect \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"Onboarding URL","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Stripe-hosted onboarding URL"}}},"example":{"url":"https://connect.stripe.com/setup/e/acct_123/..."}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/billing/connect/payout":{"post":{"operationId":"withdrawBalance","summary":"Withdraw marketplace balance to bank","description":"Transfers the seller's entire available marketplace balance to their connected bank account. Requires completed payout onboarding (POST /api/billing/connect). The balance is reserved before the transfer and restored if it fails, so a failure never loses funds.","tags":["Billing"],"x-rateLimit":{"limit":10,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/billing/connect/payout \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"Withdrawal initiated","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"amount_cents":{"type":"integer","description":"Amount transferred in cents"},"transfer_id":{"type":"string","description":"Stripe transfer id"}}},"example":{"amount_cents":45000,"transfer_id":"tr_123"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/billing/invoices":{"get":{"operationId":"listInvoices","summary":"List payment invoices","description":"Returns a list of paid invoices with invoice number, amount, date, and links to view or download the PDF. Invoices are generated automatically for every domain purchase, renewal, and transfer.","tags":["Billing"],"x-rateLimit":{"limit":30,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/billing/invoices \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Max invoices to return"}],"responses":{"200":{"description":"List of invoices","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"invoices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"string","nullable":true},"status":{"type":"string"},"amount_due":{"type":"integer","description":"Amount in cents"},"amount_paid":{"type":"integer","description":"Amount in cents"},"currency":{"type":"string"},"description":{"type":"string","nullable":true},"created":{"type":"string","format":"date-time"},"hosted_invoice_url":{"type":"string","format":"uri","nullable":true,"description":"URL to view the invoice in browser"},"invoice_pdf":{"type":"string","format":"uri","nullable":true,"description":"Direct PDF download URL"}}}},"has_more":{"type":"boolean"},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/referrals":{"get":{"operationId":"getReferrals","summary":"Get referral earnings and history","description":"Returns your unique referral code, commission rate (20%), earnings breakdown (total, paid, pending), and a history of all referred purchases. Share your referral code with others - when they register with your code (via the `ref` parameter), you earn a commission on all their future domain purchases automatically.","tags":["Referrals"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/referrals \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"Referral code, earnings, and history","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"referral_code":{"type":"string","description":"Your unique referral code to share"},"referral_rate":{"type":"integer","description":"Commission percentage (currently 20%)"},"total_earned_cents":{"type":"integer","description":"Total earnings in cents"},"total_paid_cents":{"type":"integer","description":"Total paid out in cents"},"total_pending_cents":{"type":"integer","description":"Pending payout in cents"},"referrals":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"earned_cents":{"type":"integer"},"paid_out":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}}}}},"example":{"referral_code":"x7k9m2","referral_rate":20,"total_earned_cents":400,"total_paid_cents":200,"total_pending_cents":200,"referrals":[{"id":"cm5ref001","domains":["friend-site.com"],"earned_cents":200,"paid_out":true,"created_at":"2025-01-20T10:00:00.000Z"},{"id":"cm5ref002","domains":["another.dev"],"earned_cents":200,"paid_out":false,"created_at":"2025-02-10T15:30:00.000Z"}]}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/webhooks":{"get":{"operationId":"listWebhooks","summary":"List webhooks","description":"List all webhook endpoints configured for your account. Returns URL, subscribed events, and active status for each webhook. Secrets are never returned after creation.","tags":["Webhooks"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/webhooks \\\n  -H \"Authorization: Bearer domani_sk_xxx\""}],"responses":{"200":{"description":"List of webhooks","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}}},"hint":{"type":"string"}}},"example":{"webhooks":[{"id":"cm5wh001","url":"https://example.com/webhooks/domani","events":["domain.purchased","dns.updated"],"active":true,"created_at":"2026-02-25T10:00:00.000Z"}],"hint":"1 webhook(s)."}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"post":{"operationId":"createWebhook","summary":"Create webhook","description":"Register a new webhook endpoint. The URL must use HTTPS. Choose which event types to subscribe to. The webhook secret is returned only once at creation - save it to verify incoming payloads with HMAC-SHA256. Maximum 5 webhooks per account.","tags":["Webhooks"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl -X POST https://domani.run/api/webhooks \\\n  -H \"Authorization: Bearer domani_sk_xxx\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://example.com/hook\",\"events\":[\"domain.purchased\",\"dns.updated\"]}'"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL that will receive webhook POST requests"},"events":{"type":"array","items":{"type":"string"},"description":"Event types to subscribe to. Use GET /api/webhooks/events to list available types."}}},"example":{"url":"https://example.com/webhooks/domani","events":["domain.purchased","dns.updated","transfer.completed"]}}}},"responses":{"200":{"description":"Webhook created. Secret is included only in this response.","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"secret":{"type":"string","description":"HMAC-SHA256 signing secret (shown once)"},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"hint":{"type":"string"}}},"example":{"id":"cm5wh001","url":"https://example.com/webhooks/domani","events":["domain.purchased","dns.updated"],"secret":"whsec_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345","active":true,"created_at":"2026-02-25T10:00:00.000Z","hint":"Webhook created. Save the secret - it won't be shown again. Use it to verify incoming payloads with HMAC-SHA256."}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Unknown event type(s): invalid.event","code":"INVALID_PARAMETER","hint":"Use GET /api/webhooks/events to list valid event types","documentation_url":"https://domani.run/llms.txt"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/webhooks/{id}":{"patch":{"operationId":"updateWebhook","summary":"Update webhook","description":"Update a webhook's URL, subscribed events, or active status. Send only the fields you want to change.","tags":["Webhooks"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"New HTTPS URL"},"events":{"type":"array","items":{"type":"string"},"description":"New list of event types"},"active":{"type":"boolean","description":"Set false to pause, true to resume"}}},"examples":{"pause":{"summary":"Pause webhook","value":{"active":false}},"updateEvents":{"summary":"Change events","value":{"events":["domain.purchased","transfer.completed"]}}}}}},"responses":{"200":{"description":"Webhook updated","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Webhook not found","code":"NOT_FOUND","hint":"Verify the webhook exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}},"delete":{"operationId":"deleteWebhook","summary":"Delete webhook","description":"Delete a webhook endpoint. All pending deliveries will be cancelled. This cannot be undone.","tags":["Webhooks"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook ID"}],"responses":{"200":{"description":"Webhook deleted","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"hint":{"type":"string"}}}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Webhook not found","code":"NOT_FOUND","hint":"Verify the webhook exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/webhooks/{id}/deliveries":{"get":{"operationId":"getWebhookDeliveries","summary":"List webhook deliveries","description":"Get recent delivery attempts for a webhook. Shows event type, HTTP status, number of attempts, and any errors. Useful for debugging failed deliveries.","tags":["Webhooks"],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook ID"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Maximum number of deliveries to return"}],"responses":{"200":{"description":"Delivery history","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000}},"content":{"application/json":{"schema":{"type":"object","properties":{"deliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"event_type":{"type":"string"},"status":{"type":"string","enum":["pending","delivered","failed"]},"http_status":{"type":"integer","nullable":true},"attempts":{"type":"integer"},"last_error":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}}},"hint":{"type":"string"}}},"example":{"deliveries":[{"id":"cm5del001","event_type":"domain.purchased","status":"delivered","http_status":200,"attempts":1,"last_error":null,"created_at":"2026-02-25T10:05:00.000Z"}],"hint":"1 delivery(ies) for this webhook."}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Webhook not found","code":"NOT_FOUND","hint":"Verify the webhook exists and belongs to you","documentation_url":"https://domani.run/llms.txt"}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/webhooks/events":{"get":{"operationId":"listWebhookEvents","summary":"List webhook event types","description":"List all available webhook event types with descriptions. No authentication required.","tags":["Webhooks"],"x-rateLimit":{"limit":60,"window":"1 minute"},"x-codeSamples":[{"lang":"bash","label":"cURL","source":"curl https://domani.run/api/webhooks/events"}],"responses":{"200":{"description":"Available event types","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"description":{"type":"string"}}}}}},"example":{"events":[{"type":"domain.purchased","description":"A new domain was successfully registered"},{"type":"dns.updated","description":"DNS records were changed for a domain"},{"type":"transfer.completed","description":"A domain transfer completed successfully"}]}}}}}}},"/api/domains/{domain}/email/setup":{"post":{"operationId":"setupDomainEmail","summary":"Set up email on a domain","description":"Pre-configure email DNS on a domain (optional). This is called automatically by create_mailbox when needed. Pass force=true to override existing email provider (Google Workspace, Fastmail, Proton).","tags":["Email"],"security":[{"BearerAuth":[]}],"x-rateLimit":{"limit":60,"window":"1 minute"},"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"force":{"type":"boolean","description":"Override existing email provider (Google Workspace, Fastmail, Proton). Default: false"}}}}}},"responses":{"200":{"description":"Email set up successfully","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"status":{"type":"string","enum":["configured","already_configured"]},"verified_at":{"type":"string","nullable":true},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}},"hint":{"type":"string"}}}}}},"400":{"description":"Conflict - external email provider active. Pass force=true to override"}}},"delete":{"operationId":"removeDomainEmail","summary":"Remove email from a domain","description":"Remove email from a domain, delete all mailboxes and messages, and set emailEnabled to false.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"responses":{"200":{"description":"Email removed successfully"}}}},"/api/domains/{domain}/email/status":{"get":{"operationId":"getDomainEmailStatus","summary":"Check email DNS status","description":"Check email DNS verification status for a domain. Returns whether the domain is verified and ready, DNS record details, and mailbox count.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"responses":{"200":{"description":"Email status","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"verified":{"type":"boolean"},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"}},"mailbox_count":{"type":"integer"}}}}}}}}},"/api/email":{"post":{"operationId":"createMailbox","summary":"Create a mailbox on domani.run","description":"Create a free email address on domani.run (e.g. hello@domani.run). No domain ownership required. Limited to 1 free @domani.run mailbox per user. Many common slugs are reserved.","tags":["Email"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","description":"Local part of the email address (e.g. 'hello' for hello@domani.run)"},"name":{"type":"string","description":"Display name (defaults to capitalized slug)"}}}}}},"responses":{"200":{"description":"Mailbox created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"}}}}}}}},"get":{"operationId":"listMailboxes","summary":"List all mailboxes","description":"List every mailbox the acting principal can access across all domains, including workspace grants.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"domain","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by domain"}],"responses":{"200":{"description":"Mailbox list","content":{"application/json":{"schema":{"type":"object","properties":{"mailboxes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"message_count":{"type":"integer"},"access_role":{"type":"string","enum":["viewer","responder","manager"]},"storage_quota_bytes":{"type":"integer","nullable":true},"storage_used_bytes":{"type":"integer","nullable":true},"storage_measured_at":{"type":"string","format":"date-time","nullable":true}}}}}}}}}}}},"/api/emails":{"post":{"operationId":"createMailboxByAddress","summary":"Create a mailbox","description":"Create an email address (mailbox). Provide a full address like \"hello@mysite.com\". Email DNS is auto-configured on first use. Pass force=true to override existing email provider. Max 5 mailboxes per user. For free @domani.run mailboxes use POST /api/email.\n\nPass workspace_id to create the mailbox inside a workspace you own. For a custom domain, this explicitly and atomically adopts the domain and all its unscoped sibling mailboxes into that workspace; a domain can never be split across workspaces.\n\nPass kind=\"hosted\" to create a real IMAP/SMTP mailbox on your own domain (connect Apple Mail, Thunderbird, or any client) instead of the default API mailbox (send/receive via API + webhooks). Hosted mailboxes return DNS records to publish, mail client settings, and a one-time app password. Requires a domain you own.","tags":["Email"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string","description":"Full email address, e.g. hello@mysite.com"},"name":{"type":"string","description":"Display name for outbound emails (e.g. \"John Doe\")"},"force":{"type":"boolean","description":"Override existing MX records. Default: false"},"kind":{"type":"string","enum":["api","hosted"],"description":"\"api\" (default: send/receive via API + webhooks) or \"hosted\" (real IMAP/SMTP mailbox on your domain)"},"workspace_id":{"type":"string","description":"Workspace to own the mailbox. Only the workspace owner can adopt resources."}},"required":["address"]}}}},"responses":{"201":{"description":"Mailbox created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"string"},"name":{"type":"string","nullable":true},"domain":{"type":"string"},"slug":{"type":"string"},"workspace_id":{"type":"string","nullable":true},"webhook_url":{"type":"string","nullable":true},"forward_to":{"type":"string","nullable":true},"signing_secret":{"type":"string","description":"HMAC secret for verifying inbound webhook payloads (shown once at creation)"}}}}}}}},"get":{"operationId":"listMailboxesByAddress","summary":"List all mailboxes","description":"List every mailbox the acting principal can access, including workspace grants. Same as GET /api/email.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"domain","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by domain"}],"responses":{"200":{"description":"Mailbox list","content":{"application/json":{"schema":{"type":"object","properties":{"mailboxes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"message_count":{"type":"integer"},"webhook_url":{"type":"string","nullable":true},"forward_to":{"type":"string","nullable":true},"workspace_id":{"type":"string","nullable":true},"access_role":{"type":"string","enum":["viewer","responder","manager"]},"collaboration_enabled":{"type":"boolean"},"storage_quota_bytes":{"type":"integer","nullable":true},"storage_used_bytes":{"type":"integer","nullable":true},"storage_measured_at":{"type":"string","format":"date-time","nullable":true}}}}}}}}}}}},"/api/emails/{address}":{"get":{"operationId":"getMailboxByAddress","summary":"Get mailbox details","description":"Get details for a specific mailbox by its full email address (URL-encoded, e.g. hello%40mysite.com).","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Full email address (URL-encoded, e.g. hello%40mysite.com)"}],"responses":{"200":{"description":"Mailbox details. Manager-only secrets are redacted for viewers/responders.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"kind":{"type":"string"},"workspace_id":{"type":"string","nullable":true},"access_role":{"type":"string","enum":["viewer","responder","manager"]},"webhook_url":{"type":"string","nullable":true},"forward_to":{"type":"string","nullable":true},"signing_secret":{"type":"string","nullable":true,"description":"HMAC secret for managers; null for viewers/responders"},"message_count":{"type":"integer"},"storage_quota_bytes":{"type":"integer","nullable":true},"storage_used_bytes":{"type":"integer","nullable":true},"storage_measured_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}}}}}}},"patch":{"operationId":"updateMailboxByAddress","summary":"Update mailbox","description":"Update a mailbox's display name, webhook URL, or forward-to email address by its full email address. Set to null to disable/clear.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Full email address (URL-encoded)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","nullable":true,"description":"Display name for the mailbox. Set to null to clear."},"webhook_url":{"type":"string","nullable":true,"description":"HTTPS URL for inbound email webhook, or null to clear"},"forward_to":{"type":"string","nullable":true,"description":"Email address to forward inbound emails to, or null to clear"},"drop_spam":{"type":"boolean","description":"Drop (don't store or webhook) inbound messages flagged as spam"}}}}}},"responses":{"200":{"description":"Mailbox updated","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"address":{"type":"string"},"slug":{"type":"string"},"domain":{"type":"string"},"name":{"type":"string","nullable":true},"webhook_url":{"type":"string","nullable":true},"forward_to":{"type":"string","nullable":true},"signing_secret":{"type":"string","description":"HMAC secret for verifying inbound webhook payloads"}}}}}}}},"delete":{"operationId":"deleteMailboxByAddress","summary":"Delete a mailbox","description":"Delete a mailbox by its full email address. Requires confirm=true in body. Without confirm, returns a preview with message_count.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Full email address (URL-encoded)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"boolean","description":"Must be true to actually delete. Omit to preview."}}}}}},"responses":{"200":{"description":"Mailbox deleted (if confirm=true) or preview (if omitted)"}}}},"/api/emails/{address}/send":{"post":{"operationId":"sendEmailByAddress","summary":"Send an email","description":"Send an email from a mailbox identified by its full email address. The server runs a mandatory versioned policy first: objective safety failures are denied while reputation and content-quality findings are returned as warnings. Maximum 20 unique recipients per message. Rate limit: 100 recipients per hour per mailbox.","tags":["Email"],"security":[{"BearerAuth":[]}],"x-rateLimit":{"limit":100,"window":"1 hour","scope":"per mailbox"},"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Sender email address (URL-encoded)"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Unique key to prevent duplicate sends"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"oneOf":[{"type":"string"},{"type":"array","maxItems":20,"items":{"type":"string"}}],"description":"Recipient email address(es)"},"cc":{"oneOf":[{"type":"string"},{"type":"array","maxItems":20,"items":{"type":"string"}}],"description":"CC recipient(s)"},"bcc":{"oneOf":[{"type":"string"},{"type":"array","maxItems":20,"items":{"type":"string"}}],"description":"BCC recipient(s)"},"subject":{"type":"string"},"text":{"type":"string","description":"Plain text body"},"html":{"type":"string","description":"HTML body"},"reply_to":{"type":"string","description":"Reply-To address"},"in_reply_to":{"type":"string","description":"Message-ID of the email being replied to (for threading)"},"references":{"type":"string","description":"Space-separated Message-ID chain (for threading)"},"idempotency_key":{"type":"string","description":"Stable key that prevents duplicate sends"},"allow_risky_content":{"type":"boolean","default":false,"deprecated":true,"description":"Deprecated compatibility field. Public HTTPS third-party auth links are allowed with a warning; objective safety blocks cannot be overridden."},"attachments":{"type":"array","description":"File attachments (max 10, max 40MB total). Content must be base64-encoded.","items":{"type":"object","properties":{"content":{"type":"string","description":"Base64-encoded file content"},"filename":{"type":"string","description":"Filename with extension"},"content_type":{"type":"string","description":"MIME type (optional)"}},"required":["content","filename"]}}},"required":["to"]}}}},"responses":{"200":{"description":"Email sent","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"message_id":{"type":"string","description":"RFC 5322 Message-ID"},"from":{"type":"string"},"to":{"type":"string"},"status":{"type":"string"},"attachments_count":{"type":"integer"},"suppressed":{"type":"array","items":{"type":"string"}},"deliverability":{"type":"object","description":"Versioned policy report applied to this send; inspect decision and categorized checks"}}}}}},"400":{"description":"Unsafe message blocked by the deliverability policy"},"429":{"description":"Rate limit exceeded (100/hr per mailbox)"}}}},"/api/emails/{address}/deliverability-check":{"post":{"operationId":"checkEmailDeliverabilityByAddress","summary":"Preflight an outbound email","description":"Run the exact versioned server-side policy used by the send endpoint without sending or consuming email quota. Public HTTPS authentication links on third-party domains are allowed with a reputation warning. Local/private URLs, non-HTTPS authentication links and executable attachments are blocked; bodies above 102 KB produce a clipping warning.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Sender email address (URL-encoded)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"subject":{"type":"string"},"text":{"type":"string"},"html":{"type":"string"},"idempotency_key":{"type":"string"},"allow_risky_content":{"type":"boolean","default":false,"deprecated":true,"description":"Deprecated compatibility field; objective safety blocks cannot be overridden."},"attachments":{"type":"array","maxItems":10,"items":{"type":"object","properties":{"filename":{"type":"string"},"content_type":{"type":"string"}},"required":["filename"]}}},"anyOf":[{"required":["text"]},{"required":["html"]}]}}}},"responses":{"200":{"description":"Versioned policy report","content":{"application/json":{"schema":{"type":"object","properties":{"policy_version":{"type":"string"},"decision":{"type":"string","enum":["allow","allow_with_warnings","deny"]},"safe_to_send":{"type":"boolean","description":"Backwards-compatible boolean equivalent to decision != deny"},"risk":{"type":"string","enum":["low","medium","high","blocked"]},"score":{"type":"integer","minimum":0,"maximum":100},"authentication_message":{"type":"boolean"},"checks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string","enum":["transport_safety","credential_safety","reputation","content_quality","reliability"]},"status":{"type":"string","enum":["pass","warning","blocked"]},"message":{"type":"string"},"fix":{"type":"string"},"evidence":{"type":"array","items":{"type":"string"}}},"required":["id","category","status","message"]}},"blocked_reasons":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"override_used":{"type":"boolean","deprecated":true}},"required":["policy_version","decision","safe_to_send","risk","score","checks","blocked_reasons","warnings"]}}}},"404":{"description":"Mailbox not found"}}}},"/api/emails/{address}/messages":{"get":{"operationId":"listEmailMessagesByAddress","summary":"List emails","description":"List emails in a canonical folder or virtual view. Defaults to Inbox. Folder location is independent from message direction and spam verdict.\n\nAuthentication mail (OTPs / verification codes, password resets, magic links) is tagged `security: \"auth\"`. Tokens without the `email:auth_secrets` scope see those messages with subject and body REDACTED (`redacted: true`) - metadata (from, date) stays visible.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Pagination cursor from previous response"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"maximum":100},"description":"Max messages to return"},{"name":"direction","in":"query","required":false,"schema":{"type":"string","enum":["in","out","all"]},"description":"Filter by direction (default: all)"},{"name":"folder","in":"query","required":false,"schema":{"type":"string","enum":["inbox","archive","sent","spam","trash"]},"description":"System folder. Mutually exclusive with view. Defaults to inbox."},{"name":"view","in":"query","required":false,"schema":{"type":"string","enum":["starred","all"]},"description":"Virtual view. Mutually exclusive with folder."},{"name":"since","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"ISO timestamp - return only messages created after this date"},{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by sender address"},{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by recipient address"},{"name":"subject","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by subject"},{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Broad case-insensitive search across sender, recipients, subject, and plain-text body"},{"name":"unread","in":"query","required":false,"schema":{"type":"boolean"},"description":"Return unread messages only"},{"name":"attachments","in":"query","required":false,"schema":{"type":"boolean"},"description":"Return messages that contain attachments only"},{"name":"spam","in":"query","required":false,"schema":{"type":"boolean"},"description":"Filter by spam flag (pass false to hide spam-flagged inbound)"}],"responses":{"200":{"description":"Message list","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"message_id":{"type":"string","nullable":true},"direction":{"type":"string","enum":["in","out"]},"folder":{"type":"string","enum":["inbox","archive","sent","spam","trash"]},"read":{"type":"boolean"},"starred":{"type":"boolean"},"answered":{"type":"boolean"},"forwarded":{"type":"boolean"},"spam_detected":{"type":"boolean"},"trashed_at":{"type":"string","format":"date-time","nullable":true},"from":{"type":"string"},"to":{"type":"string"},"cc":{"type":"string","nullable":true},"reply_to":{"type":"string","nullable":true},"subject":{"type":"string"},"text":{"type":"string"},"in_reply_to":{"type":"string","nullable":true},"references":{"type":"string","nullable":true},"status":{"type":"string"},"events":{"type":"array","items":{"type":"object"}},"created_at":{"type":"string","format":"date-time"}}}},"next_cursor":{"type":"string","nullable":true}}}}}}}}},"/api/emails/{address}/folders":{"get":{"operationId":"listEmailFoldersByAddress","summary":"List email folders and counts","description":"Return server-derived counts for system folders and virtual views, plus lifecycle capabilities for the mailbox backend.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Folder counts","content":{"application/json":{"schema":{"type":"object","properties":{"folders":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["inbox","archive","sent","drafts","spam","trash"]},"total":{"type":"integer"},"unread":{"type":"integer"}}}},"views":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["starred","all"]},"total":{"type":"integer"},"unread":{"type":"integer"}}}},"capabilities":{"type":"object"}}}}}},"404":{"description":"Mailbox not found"}}}},"/api/emails/{address}/messages/actions":{"post":{"operationId":"updateEmailMessagesByAddress","summary":"Apply a lifecycle action to messages","description":"Move, restore, mark read, star, or permanently delete up to 100 explicit message IDs. Moving to Trash is reversible. Permanent deletion requires `email:delete` and only accepts messages already in Trash. Returns 207 when only part of the batch succeeds.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"message_ids":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string"}},"action":{"type":"string","enum":["move","mark_read","star","restore","delete_permanently"]},"destination":{"type":"string","enum":["inbox","archive","sent","spam","trash"]},"read":{"type":"boolean"},"starred":{"type":"boolean"}},"required":["message_ids","action"]}}}},"responses":{"200":{"description":"All requested actions completed"},"207":{"description":"Some message actions failed; inspect each result"},"403":{"description":"Permanent deletion requires email:delete"}}}},"/api/emails/{address}/messages/read":{"patch":{"operationId":"markMessagesReadByAddress","summary":"Mark messages as read or unread","description":"Mark one or more messages as read or unread in a mailbox identified by its full email address.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"message_ids":{"type":"array","items":{"type":"string"},"description":"IDs of messages to mark"},"read":{"type":"boolean","description":"true to mark as read, false to mark as unread"}},"required":["message_ids","read"]}}}},"responses":{"200":{"description":"Messages updated","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"}}}}}}}}},"/api/emails/{address}/messages/delete":{"post":{"operationId":"deleteMessagesByAddress","summary":"Bulk delete messages","description":"Move multiple messages to Trash. This is reversible and delegates to the canonical lifecycle action.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"message_ids":{"type":"array","items":{"type":"string"},"maxItems":100,"description":"IDs of messages to delete"}},"required":["message_ids"]}}}},"responses":{"200":{"description":"Messages deleted","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"}}}}}},"404":{"description":"Mailbox not found"}}}},"/api/emails/{address}/messages/{id}":{"get":{"operationId":"getMessageByAddress","summary":"Get a message","description":"Fetch a single message by ID from a mailbox identified by its full email address. Messages classified as authentication mail (OTP, password reset, magic link) come back with subject/body redacted unless the token has the `email:auth_secrets` scope.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Message ID"}],"responses":{"200":{"description":"Message details","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"message_id":{"type":"string","nullable":true},"direction":{"type":"string","enum":["in","out"]},"from":{"type":"string"},"to":{"type":"string"},"cc":{"type":"string","nullable":true},"reply_to":{"type":"string","nullable":true},"subject":{"type":"string"},"text":{"type":"string","nullable":true},"html":{"type":"string","nullable":true},"in_reply_to":{"type":"string","nullable":true},"references":{"type":"string","nullable":true},"attachments":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string"},"content_type":{"type":"string"},"size":{"type":"integer"},"url":{"type":"string","nullable":true}}}},"status":{"type":"string"},"is_read":{"type":"boolean"},"read_at":{"type":"string","nullable":true},"events":{"type":"array","items":{"type":"object","properties":{"status":{"type":"string"},"detail":{"type":"object","nullable":true},"created_at":{"type":"string","format":"date-time"}}}},"created_at":{"type":"string","format":"date-time"}}}}}},"404":{"description":"Mailbox or message not found"}}},"delete":{"operationId":"deleteMessageByAddress","summary":"Delete a message","description":"Move a message to Trash. This is reversible. Use the lifecycle action with delete_permanently and an email:delete token to erase a message already in Trash.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Message ID"}],"responses":{"200":{"description":"Message deleted","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean"}}}}}},"404":{"description":"Mailbox or message not found"}}}},"/api/emails/{address}/messages/{id}/reply":{"post":{"operationId":"replyToMessageByAddress","summary":"Reply to a message","description":"Reply to a message in a mailbox identified by its full email address. Threading headers are auto-populated.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Message ID to reply to"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Plain text reply body"},"html":{"type":"string","description":"HTML reply body"},"cc":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Additional CC recipient(s)"},"all":{"type":"boolean","default":false,"description":"Reply-all: auto-populate CC from original To/CC"}}}}}},"responses":{"200":{"description":"Reply sent","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"message_id":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"},"status":{"type":"string"}}}}}},"400":{"description":"Missing body (provide text or html)"},"404":{"description":"Mailbox or message not found"}}}},"/api/emails/{address}/messages/{id}/forward":{"post":{"operationId":"forwardMessageByAddress","summary":"Forward a message","description":"Forward a message from a mailbox identified by its full email address to another recipient. Forwarding authentication mail (OTP, password reset, magic link) requires the `email:auth_secrets` scope - it would exfiltrate the secret.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Message ID to forward"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Recipient email address"},"text":{"type":"string","description":"Optional note to prepend"}},"required":["to"]}}}},"responses":{"200":{"description":"Message forwarded","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"message_id":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"},"status":{"type":"string"}}}}}},"403":{"description":"Forwarding auth mail requires the email:auth_secrets scope (INSUFFICIENT_SCOPE)"},"404":{"description":"Mailbox or message not found"}}}},"/api/emails/{address}/avatar":{"get":{"operationId":"getMailboxAvatarByAddress","summary":"Get mailbox avatar info","description":"Returns the Gravatar URL (if set) and signup link for a mailbox identified by its full email address.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"responses":{"200":{"description":"Avatar info","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"gravatar_url":{"type":"string","nullable":true},"gravatar_signup":{"type":"string"},"has_avatar":{"type":"boolean"},"hint":{"type":"string"}}}}}}}}},"/api/emails/{address}/webhook":{"get":{"operationId":"getMailboxWebhook","summary":"Get mailbox webhook config","description":"Returns the webhook URL, signing secret, and status for a mailbox.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"responses":{"200":{"description":"Webhook config","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"webhook_url":{"type":"string","nullable":true},"signing_secret":{"type":"string","nullable":true},"has_webhook":{"type":"boolean"},"hint":{"type":"string"}}}}}}}},"put":{"operationId":"setMailboxWebhook","summary":"Set mailbox webhook","description":"Set or update the inbound webhook URL for a mailbox. Incoming emails will be POSTed to this URL with HMAC-SHA256 signing.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"HTTPS webhook URL"}}}}}},"responses":{"200":{"description":"Webhook set","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"webhook_url":{"type":"string"},"signing_secret":{"type":"string"},"has_webhook":{"type":"boolean"},"hint":{"type":"string"}}}}}}}},"delete":{"operationId":"removeMailboxWebhook","summary":"Remove mailbox webhook","description":"Remove the webhook URL and signing secret from a mailbox. Inbound emails will only be stored.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"responses":{"200":{"description":"Webhook removed","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"webhook_url":{"type":"string","nullable":true},"signing_secret":{"type":"string","nullable":true},"has_webhook":{"type":"boolean"},"hint":{"type":"string"}}}}}}}}},"/api/emails/{address}/webhook/rotate":{"post":{"operationId":"rotateMailboxWebhookSecret","summary":"Rotate webhook signing secret","description":"Regenerate the HMAC-SHA256 signing secret for a mailbox webhook. The old secret is immediately invalidated.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"responses":{"200":{"description":"Secret rotated","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"webhook_url":{"type":"string"},"signing_secret":{"type":"string"},"has_webhook":{"type":"boolean"},"hint":{"type":"string"}}}}}}}}},"/api/emails/{address}/webhook/test":{"post":{"operationId":"testMailboxWebhook","summary":"Test mailbox webhook","description":"Send a signed test payload to the mailbox webhook URL. Returns HTTP status and whether delivery succeeded.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"responses":{"200":{"description":"Test result","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"webhook_url":{"type":"string"},"status":{"type":"integer"},"success":{"type":"boolean"},"hint":{"type":"string"}}}}}}}}},"/api/emails/{address}/aliases":{"get":{"operationId":"listMailboxAliases","summary":"List mailbox aliases","description":"List all alias addresses that deliver into a mailbox. Aliases let several addresses (sales@, hello@, contact@) share one inbox without using a mailbox slot.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"responses":{"200":{"description":"Alias list","content":{"application/json":{"schema":{"type":"object","properties":{"mailbox":{"type":"string"},"aliases":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}}},"hint":{"type":"string"}}}}}}}},"post":{"operationId":"addMailboxAlias","summary":"Add a mailbox alias","description":"Add an alias address that delivers into this mailbox, without using a mailbox slot. The alias must be on the same domain as the mailbox. Provide a bare slug (\"sales\") or a full address (\"sales@mysite.com\").","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["alias"],"properties":{"alias":{"type":"string","description":"Alias address - a bare slug or full slug@domain on the same domain"}}}}}},"responses":{"201":{"description":"Alias created","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"mailbox":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"hint":{"type":"string"}}}}}},"409":{"description":"Address is already a mailbox or an existing alias"}}}},"/api/emails/{address}/aliases/{alias}":{"delete":{"operationId":"removeMailboxAlias","summary":"Remove a mailbox alias","description":"Remove an alias from a mailbox. Email to that address stops being delivered.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"},{"name":"alias","in":"path","required":true,"schema":{"type":"string"},"description":"Alias address to remove (URL-encoded, or a bare slug)"}],"responses":{"200":{"description":"Alias removed","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"deleted":{"type":"boolean"},"hint":{"type":"string"}}}}}},"404":{"description":"Alias not found on this mailbox"}}}},"/api/emails/{address}/client-settings":{"get":{"operationId":"getMailboxClientSettings","summary":"Get mail client settings (hosted)","description":"Get IMAP/SMTP connection settings for a hosted mailbox, to configure Apple Mail, Thunderbird, or any mail client. Username is the full address; the password is an app password (create one with POST /api/emails/{address}/credentials). Hosted mailboxes only.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Hosted mailbox address (URL-encoded)"}],"responses":{"200":{"description":"Client settings","content":{"application/json":{"schema":{"type":"object","properties":{"mailbox":{"type":"string"},"username":{"type":"string"},"imap":{"type":"object","properties":{"host":{"type":"string"},"port":{"type":"integer"},"security":{"type":"string"}}},"smtp":{"type":"object","properties":{"host":{"type":"string"},"port":{"type":"integer"},"security":{"type":"string"}}},"hint":{"type":"string"}}}}}},"400":{"description":"Not a hosted mailbox"}}}},"/api/emails/{address}/credentials":{"get":{"operationId":"listMailboxCredentials","summary":"List app passwords (hosted)","description":"List the app passwords for a hosted mailbox. Secrets are shown only once at creation; this returns labels and metadata only. Hosted mailboxes only.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Hosted mailbox address (URL-encoded)"}],"responses":{"200":{"description":"App password list","content":{"application/json":{"schema":{"type":"object","properties":{"mailbox":{"type":"string"},"credentials":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":"string","format":"date-time","nullable":true},"created_by":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["user","token","agent"]},"id":{"type":"string"},"label":{"type":"string"}}}}}},"hint":{"type":"string"}}}}}}}},"post":{"operationId":"createMailboxCredential","summary":"Create an app password (hosted)","description":"Create an app password for a hosted mailbox, used as the password in a mail client (IMAP/SMTP). The secret is returned once - store it now. Hosted mailboxes only.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Hosted mailbox address (URL-encoded)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","description":"Label to identify this app password, e.g. \"Laptop Mail\""}}}}}},"responses":{"201":{"description":"App password created (secret shown once)","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"password":{"type":"string","description":"The app password - shown once, store it now"},"client_settings":{"type":"object"},"hint":{"type":"string"}}}}}},"403":{"description":"Email hosting not enabled for this account"}}}},"/api/emails/{address}/credentials/{id}":{"delete":{"operationId":"revokeMailboxCredential","summary":"Revoke an app password (hosted)","description":"Revoke an app password. Any mail client using it stops connecting immediately. Hosted mailboxes only.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Hosted mailbox address (URL-encoded)"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"App password id (from the list endpoint)"}],"responses":{"200":{"description":"App password revoked","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"revoked":{"type":"boolean"},"hint":{"type":"string"}}}}}},"404":{"description":"App password not found"}}}},"/api/emails/{address}/rules":{"get":{"operationId":"listMailRules","summary":"List inbound mail rules","description":"List a mailbox's inbound filtering rules, in the priority order they are applied (first match wins).","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"responses":{"200":{"description":"Rule list","content":{"application/json":{"schema":{"type":"object","properties":{"mailbox":{"type":"string"},"rules":{"type":"array","items":{"$ref":"#/components/schemas/MailRule"}},"hint":{"type":"string"}}}}}}}},"post":{"operationId":"addMailRule","summary":"Add an inbound mail rule","description":"Add a rule that runs on inbound messages matching a field (from/to/subject/body). Actions: drop, mark_read, forward (action_arg = address), webhook_only (skip forward-to), label (action_arg = label). Rules apply in priority order (lower first); first match wins.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["match_field","match_op","match_value","action"],"properties":{"match_field":{"type":"string","enum":["from","to","subject","body"]},"match_op":{"type":"string","enum":["contains","equals","regex"]},"match_value":{"type":"string"},"action":{"type":"string","enum":["drop","mark_read","forward","webhook_only","label"]},"action_arg":{"type":"string","description":"Forward address (for forward) or label value (for label)"},"priority":{"type":"integer","description":"Lower runs first (default 0)"},"enabled":{"type":"boolean","description":"Default true"}}}}}},"responses":{"201":{"description":"Rule created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MailRule"}}}}}}},"/api/emails/{address}/rules/{ruleId}":{"delete":{"operationId":"removeMailRule","summary":"Remove an inbound mail rule","description":"Remove an inbound filtering rule from a mailbox.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Mailbox email address (URL-encoded)"},{"name":"ruleId","in":"path","required":true,"schema":{"type":"string"},"description":"The rule ID"}],"responses":{"200":{"description":"Rule removed","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean"},"hint":{"type":"string"}}}}}},"404":{"description":"Rule not found on this mailbox"}}}},"/api/domains/{domain}/email/catch-all":{"put":{"operationId":"setCatchAll","summary":"Set domain catch-all","description":"Route every email sent to an unmatched address on the domain into a designated mailbox. Anything that does not match a mailbox, subaddress, or alias lands in the catch-all. The mailbox must already exist on the domain.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["mailbox"],"properties":{"mailbox":{"type":"string","description":"Catch-all mailbox - a bare slug or full address on this domain"}}}}}},"responses":{"200":{"description":"Catch-all set","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"catch_all":{"type":"string","nullable":true},"hint":{"type":"string"}}}}}}}},"delete":{"operationId":"clearCatchAll","summary":"Clear domain catch-all","description":"Remove the catch-all on a domain. Email to unmatched addresses will be dropped again.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string"},"description":"Domain name"}],"responses":{"200":{"description":"Catch-all cleared","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"},"catch_all":{"type":"string","nullable":true},"hint":{"type":"string"}}}}}}}}},"/api/workspaces/{id}/ownership-transfer":{"post":{"operationId":"requestWorkspaceOwnershipTransfer","summary":"Request a workspace ownership transfer","description":"Owner-only. Sends a 48-hour acceptance link to an existing member. Nothing moves until that authenticated member accepts.","tags":["Collaboration"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["membership_id"],"properties":{"membership_id":{"type":"string"}}}}}},"responses":{"201":{"description":"Ownership transfer requested"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/workspaces/{id}/ownership-transfer/{transferId}":{"delete":{"operationId":"revokeWorkspaceOwnershipTransfer","summary":"Revoke a pending ownership transfer","tags":["Collaboration"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"transferId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Ownership transfer revoked"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/workspaces/ownership-transfers/accept":{"post":{"operationId":"acceptWorkspaceOwnershipTransfer","summary":"Accept workspace ownership","description":"Target-only. Atomically transfers the workspace, scoped domains and mailboxes; the previous owner becomes an admin and the existing payer remains unchanged.","tags":["Collaboration"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"}}}}}},"responses":{"200":{"description":"Ownership transfer receipt"},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing":{"summary":"No Authorization header","value":{"error":"Missing API key","code":"MISSING_API_KEY","hint":"Include 'Authorization: Bearer domani_sk_xxx' header","documentation_url":"https://domani.run/llms.txt"}},"invalid":{"summary":"Invalid or revoked key","value":{"error":"Invalid API key","code":"INVALID_API_KEY","hint":"Check your API key or create a new one at POST /api/tokens","documentation_url":"https://domani.run/llms.txt"}},"expired":{"summary":"Token has expired","value":{"error":"API key has expired","code":"EXPIRED_API_KEY","hint":"Create a new token via POST /api/tokens or run 'domani login'","documentation_url":"https://domani.run/llms.txt"}}}}}},"429":{"description":"Rate limit exceeded - wait and retry","headers":{"X-RateLimit-Limit":{"description":"Maximum requests allowed in the current window","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window","schema":{"type":"integer"},"example":57},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the window resets","schema":{"type":"integer"},"example":1700000000},"Retry-After":{"description":"Seconds to wait before retrying","schema":{"type":"integer"},"example":30}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":"Rate limit exceeded","code":"RATE_LIMIT_EXCEEDED","hint":"Wait 30 seconds before retrying","retry_after":30,"documentation_url":"https://domani.run/llms.txt"}}}}}}},"/api/suppressions":{"get":{"operationId":"listSuppressions","summary":"List suppressed addresses","description":"List addresses on your suppression list - hard bounces and complaints (ingested automatically from delivery events) plus manual entries. Sends to these addresses are skipped. Cursor-paginated.","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Pagination cursor from a previous response"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"Max entries (default 50, max 100)"}],"responses":{"200":{"description":"Suppression list","content":{"application/json":{"schema":{"type":"object","properties":{"suppressions":{"type":"array","items":{"type":"object","properties":{"address":{"type":"string"},"reason":{"type":"string","enum":["hard_bounce","complaint","manual"]},"source":{"type":"string","enum":["resend","api"]},"created_at":{"type":"string","format":"date-time"}}}},"next_cursor":{"type":"string","nullable":true},"hint":{"type":"string"}}}}}}}},"post":{"operationId":"addSuppression","summary":"Add a suppression","description":"Manually add an address to your suppression list so future sends skip it. Hard bounces and complaints are added automatically; use this for addresses you want to stop emailing. Idempotent.","tags":["Email"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address"],"properties":{"address":{"type":"string","description":"Email address to suppress"},"reason":{"type":"string","enum":["manual","hard_bounce","complaint"],"description":"Reason (default: manual)"}}}}}},"responses":{"201":{"description":"Address suppressed","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"reason":{"type":"string"},"source":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"hint":{"type":"string"}}}}}}}}},"/api/suppressions/{address}":{"delete":{"operationId":"removeSuppression","summary":"Remove a suppression","description":"Remove an address from your suppression list so you can email it again (e.g. after the recipient fixed their mailbox).","tags":["Email"],"security":[{"BearerAuth":[]}],"parameters":[{"name":"address","in":"path","required":true,"schema":{"type":"string"},"description":"Suppressed email address (URL-encoded)"}],"responses":{"200":{"description":"Suppression removed","content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"deleted":{"type":"boolean"},"hint":{"type":"string"}}}}}},"404":{"description":"Address not on the suppression list"}}}}}}