{"openapi":"3.0.3","info":{"title":"Eli API","version":"2.0.0","description":"Read AI-search evidence and execute reviewed own-site changes through Eli's guarded decision core. Shipping writes require literal JSON confirmation, plan and protocol caps, an owner/admin principal, and an audit receipt. Third-party sends and autonomy switches are not exposed.","contact":{"name":"Eli","url":"https://hireeli.io"}},"servers":[{"url":"https://hireeli.io"}],"tags":[{"name":"Public","description":"Anonymous, public-tenant-scoped resources."},{"name":"Workspace reads","description":"Tenant-pinned evidence and pending work."},{"name":"Own-site execution","description":"Confirmed, capped and audited decisions."},{"name":"Legacy","description":"Deprecated read-only REST v1."}],"components":{"securitySchemes":{"eliApiKey":{"type":"http","scheme":"bearer","bearerFormat":"ELI_API_KEY","description":"A scoped key in the eli_live_<key_id>_<secret> format. The plaintext is shown only when the key is created. The validated key row pins the workspace."},"eliUserToken":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A current Eli/Supabase user access token. Row-level security and current owner/admin membership govern writes."}},"parameters":{"WorkspaceHeader":{"name":"x-eli-tenant","in":"header","required":false,"description":"Workspace UUID. Required for user tokens with multiple memberships. For API keys it is only an equality assertion against the key-pinned workspace.","schema":{"type":"string","format":"uuid"}},"ResourceId":{"name":"id","in":"path","required":true,"description":"Tenant-scoped resource UUID.","schema":{"type":"string","format":"uuid"}}},"responses":{"Unauthorized":{"description":"Credential missing, invalid, expired or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Workspace, role, scope, plan or feature does not permit this operation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"The resource is not visible in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Current lifecycle state conflicts with the requested decision.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Request or durable protocol cap reached.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before the in-memory request window resets, when applicable."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unavailable":{"description":"A required security, billing, cap, audit, evidence or storage check is unavailable. Writes fail closed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"code":{"type":"string","nullable":true},"details":{"type":"object","additionalProperties":true,"nullable":true}},"additionalProperties":true},"WorkspaceData":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"Resource-specific data, always pinned to the resolved workspace.","additionalProperties":true},"workspaceId":{"type":"string","format":"uuid"}},"additionalProperties":true},"ProtocolReceipt":{"type":"object","required":["decision","resourceId","status","url","revertible","revert_hint","caps","audit_id"],"properties":{"decision":{"type":"string","description":"The exact accepted operation.","example":"apply"},"resourceId":{"type":"string","description":"The decided resource ID."},"status":{"type":"string","description":"The state Eli verified after the decision.","example":"applied"},"url":{"type":"string","format":"uri","nullable":true},"revertible":{"type":"boolean","description":"Whether Eli exposes a guarded machine revert for this completed action."},"revert_hint":{"type":"string","nullable":true,"description":"The exact safe next step for a revert or immutable follow-up."},"caps":{"type":"object","nullable":true,"required":["used","limit","window"],"properties":{"used":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":0},"window":{"type":"string","enum":["day"]}},"additionalProperties":false,"description":"Durable protocol write counter returned by the shared execution core."},"audit_id":{"type":"string","format":"uuid","nullable":true,"description":"Durable protocol-decision audit row for this machine write."}},"additionalProperties":true},"ConfirmationRequired":{"type":"object","required":["error","message","required","preview"],"properties":{"error":{"type":"string","enum":["confirmation_required"]},"message":{"type":"string","description":"Plain instruction to show the preview and re-call only after human approval."},"required":{"type":"object","required":["confirm"],"properties":{"confirm":{"$ref":"#/components/schemas/LiteralConfirmation"}},"additionalProperties":false},"preview":{"type":"object","additionalProperties":true,"description":"The current before/after diff, draft or layer evidence. No write occurred."}},"additionalProperties":true},"LiteralConfirmation":{"type":"boolean","enum":[true],"description":"Must be the JSON boolean true. Strings, numbers and free-text phrases are rejected."},"OnsiteDecisionRequest":{"type":"object","required":["action","confirm"],"properties":{"action":{"type":"string","enum":["approve","apply","revert","dismiss"]},"confirm":{"$ref":"#/components/schemas/LiteralConfirmation"}},"additionalProperties":false},"ContentDecisionRequest":{"type":"object","required":["action","confirm"],"description":"approve_publish requires write:drafts and write:own-site for an API key. dismiss requires write:drafts.","properties":{"action":{"type":"string","enum":["approve_publish","dismiss"]},"confirm":{"$ref":"#/components/schemas/LiteralConfirmation"},"provider":{"type":"string","enum":["wordpress","webflow","shopify","contentful","sanity","strapi","generic_api","manual_url"],"description":"Optional connected CMS choice. Use manual_url only with publication_url after the page is publicly live."},"publication_url":{"type":"string","format":"uri","maxLength":2000,"description":"Exact public URL used only with provider manual_url so Eli can verify a human publication handoff."}},"additionalProperties":false},"CorrectionDecisionRequest":{"type":"object","required":["action","confirm"],"description":"Requires write:own-site for an API key.","properties":{"action":{"type":"string","enum":["approve","dismiss"]},"confirm":{"$ref":"#/components/schemas/LiteralConfirmation"}},"additionalProperties":false},"LayerDecisionRequest":{"type":"object","required":["confirm"],"description":"Requires write:own-site for an API key.","properties":{"confirm":{"$ref":"#/components/schemas/LiteralConfirmation"}},"additionalProperties":false},"ScanRequest":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","example":"example.com"}},"additionalProperties":false},"ScanResult":{"type":"object","required":["domain","score","readability","usability","scannedAt"],"properties":{"domain":{"type":"string"},"score":{"type":"integer","minimum":0,"maximum":100},"visibility":{"type":"integer","minimum":0,"maximum":100,"nullable":true},"readability":{"type":"integer","minimum":0,"maximum":100},"usability":{"type":"integer","minimum":0,"maximum":100},"quotes":{"type":"array","items":{"type":"object","additionalProperties":true}},"gaps":{"type":"array","items":{"type":"object","additionalProperties":true}},"scannedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/api/scan":{"post":{"tags":["Public"],"operationId":"runPublicScan","summary":"Run or read the cached public visibility scan for a domain","description":"Anonymous and public-tenant isolated. The seven-day cache, domain lease and public request/cost caps are reused; callers cannot request a fresh-cache bypass.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanRequest"}}}},"responses":{"200":{"description":"Public scan result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanResult"}}}},"400":{"description":"Invalid domain.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/api/v2/{resource}":{"get":{"tags":["Workspace reads"],"operationId":"readWorkspaceResourceV2","summary":"Read an Eli workspace resource","description":"Uses an API key pinned to one workspace or a current user token resolved through RLS. Add ?id=<uuid> to onsite-changes or content-drafts for full detail.","security":[{"eliApiKey":[]},{"eliUserToken":[]}],"parameters":[{"name":"resource","in":"path","required":true,"schema":{"type":"string","enum":["overview","competitors","traffic","revenue","actions","prompts","work-log","onsite-changes","content-drafts"]}},{"$ref":"#/components/parameters/WorkspaceHeader"},{"name":"id","in":"query","required":false,"description":"Optional resource UUID; supported by onsite-changes and content-drafts for detail.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workspace-pinned resource data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceData"}}}},"400":{"description":"Invalid workspace or detail selector.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/api/v2/onsite-changes/{id}":{"post":{"tags":["Own-site execution"],"operationId":"decideOnsiteChange","summary":"Approve, apply, revert or dismiss an on-site change","security":[{"eliApiKey":[]},{"eliUserToken":[]}],"parameters":[{"$ref":"#/components/parameters/ResourceId"},{"$ref":"#/components/parameters/WorkspaceHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnsiteDecisionRequest"}}}},"responses":{"200":{"description":"The decision completed. The response is a machine-readable receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolReceipt"}}}},"400":{"description":"Invalid JSON body, action, resource ID or publication target. No write occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Literal confirmation is missing/non-boolean, or the resource lifecycle conflicts with the decision. No unverified write should be assumed.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ConfirmationRequired"},{"$ref":"#/components/schemas/Error"}]}}}},"422":{"description":"Stored content failed the mandatory safety or evidence gate. Nothing was published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/api/v2/content-drafts/{id}":{"post":{"tags":["Own-site execution"],"operationId":"decideContentDraft","summary":"Approve and publish, or dismiss, a content draft","description":"Publication uses the connected CMS and its verified target. The response can report a verified manual handoff when direct publication is unavailable.","security":[{"eliApiKey":[]},{"eliUserToken":[]}],"parameters":[{"$ref":"#/components/parameters/ResourceId"},{"$ref":"#/components/parameters/WorkspaceHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentDecisionRequest"}}}},"responses":{"200":{"description":"The decision completed. The response is a machine-readable receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolReceipt"}}}},"400":{"description":"Invalid JSON body, action, resource ID or publication target. No write occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Literal confirmation is missing/non-boolean, or the resource lifecycle conflicts with the decision. No unverified write should be assumed.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ConfirmationRequired"},{"$ref":"#/components/schemas/Error"}]}}}},"422":{"description":"Stored content failed the mandatory safety or evidence gate. Nothing was published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/api/v2/corrections/{id}":{"post":{"tags":["Own-site execution"],"operationId":"decideCorrection","summary":"Approve or dismiss a tenant-scoped correction","security":[{"eliApiKey":[]},{"eliUserToken":[]}],"parameters":[{"$ref":"#/components/parameters/ResourceId"},{"$ref":"#/components/parameters/WorkspaceHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CorrectionDecisionRequest"}}}},"responses":{"200":{"description":"The decision completed. The response is a machine-readable receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolReceipt"}}}},"400":{"description":"Invalid JSON body, action, resource ID or publication target. No write occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Literal confirmation is missing/non-boolean, or the resource lifecycle conflicts with the decision. No unverified write should be assumed.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ConfirmationRequired"},{"$ref":"#/components/schemas/Error"}]}}}},"422":{"description":"Stored content failed the mandatory safety or evidence gate. Nothing was published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/api/v2/layer/publish":{"post":{"tags":["Own-site execution"],"operationId":"publishAiLayer","summary":"Publish the reviewed AI-readable layer","description":"Publishes the current draft through the tenant-scoped RPC and requests discovery refresh. It does not enable autonomy or send to third parties.","security":[{"eliApiKey":[]},{"eliUserToken":[]}],"parameters":[{"$ref":"#/components/parameters/WorkspaceHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LayerDecisionRequest"}}}},"responses":{"200":{"description":"The decision completed. The response is a machine-readable receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProtocolReceipt"}}}},"400":{"description":"Invalid JSON body, action, resource ID or publication target. No write occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Literal confirmation is missing/non-boolean, or the resource lifecycle conflicts with the decision. No unverified write should be assumed.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ConfirmationRequired"},{"$ref":"#/components/schemas/Error"}]}}}},"422":{"description":"Stored content failed the mandatory safety or evidence gate. Nothing was published.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/Unavailable"}}}},"/api/v1/{resource}":{"get":{"tags":["Legacy"],"operationId":"readWorkspaceResourceV1","summary":"Read a legacy workspace resource","deprecated":true,"description":"Read-only compatibility endpoint for raw Eli user access tokens. New integrations should use REST v2 and scoped API keys.","security":[{"eliUserToken":[]}],"parameters":[{"name":"resource","in":"path","required":true,"schema":{"type":"string","enum":["overview","competitors","traffic","revenue"]}},{"$ref":"#/components/parameters/WorkspaceHeader"}],"responses":{"200":{"description":"Legacy workspace resource."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/llms.txt":{"get":{"tags":["Public"],"operationId":"getOwnLlmsTxt","summary":"Read Eli's published AI-readable summary","responses":{"200":{"description":"Plain-text llms.txt.","content":{"text/plain":{}}}}}},"/capabilities.json":{"get":{"tags":["Public"],"operationId":"getOwnCapabilities","summary":"Read Eli's published capabilities and public action URLs","responses":{"200":{"description":"Published capabilities.","content":{"application/json":{}}}}}},"/l/{slug}/llms.txt":{"get":{"tags":["Public"],"operationId":"getPublishedClientLlmsTxt","summary":"Read a customer's published AI-readable layer","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Published plain text.","content":{"text/plain":{}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/l/{slug}/capabilities.json":{"get":{"tags":["Public"],"operationId":"getPublishedClientCapabilities","summary":"Read a customer's published capabilities","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Published capabilities.","content":{"application/json":{}}},"404":{"$ref":"#/components/responses/NotFound"}}}}}}