> ## Agent Instructions > Use a clmt_test_ key while developing. It never touches live data. Send a UUID Idempotency-Key on every POST, PUT and DELETE, generated once per operation and reused on retries. Pin Clemta-Version: 2026-08-13 on every request. Branch on the error code field, never on detail. Retry only timeouts, 5xx and 429, and honor Retry-After. Test companies never advance on their own. Drive them with POST /sandbox/companies/{id}/simulate. OpenAPI: https://api.clemta.com/v1/openapi.json. Skills: npx skills add https://docs.clemta.com. Docs search MCP: https://docs.clemta.com/mcp. Guide: https://docs.clemta.com/partner/ai-agents.md. # Clemta MCP server Source: https://docs.clemta.com/ai/clemta-mcp Ask Clemta instead of opening it, from Claude, Cursor, or any MCP client. In development. Connection details will be published here when the server ships. The Clemta MCP server puts Clemta inside the tools you already talk to. Connect an MCP client, and ask in plain words. ## Who it is for * **People using the Clemta app.** Ask about your own company: what is due, what arrived, what is still needed from you. * **Partner teams.** An operations team connects with a Partner API key and asks about the companies it formed: which ones are waiting on a document, what stage an order is at, when a filing is due. The answers come from the same objects the Partner API serves, with no code in between. The key sets what the agent can see. A test key sees the sandbox and nothing else. This is separate from the [docs search server](/ai/coding-agents#docs-search-mcp), which searches these pages and nothing else. # Docs for agents Source: https://docs.clemta.com/ai/coding-agents A docs search server, Markdown pages, and llms.txt for Claude Code, Cursor, or any coding agent. Every page on this site is also served in a form an agent can read. None of it needs a key. Product-specific skills are listed by product, starting with the [Partner API](/ai/partner-api). ## Docs search (MCP) A search server for these pages runs at `https://docs.clemta.com/mcp`. It searches the docs and does not call the API. To use Clemta itself from an agent, see the [Clemta MCP server](/ai/clemta-mcp). ```bash Claude Code theme={null} claude mcp add --transport http clemta-docs https://docs.clemta.com/mcp ``` ```json Cursor (.cursor/mcp.json) theme={null} { "mcpServers": { "clemta-docs": { "url": "https://docs.clemta.com/mcp" } } } ``` ```json VS Code (.vscode/mcp.json) theme={null} { "servers": { "clemta-docs": { "type": "http", "url": "https://docs.clemta.com/mcp" } } } ``` The **Connect** entries in the menu at the top of every page do the same in one click. ## Markdown and llms.txt * Add `.md` to any page URL for its Markdown: `https://docs.clemta.com/partner/webhooks.md`. * [`/llms.txt`](https://docs.clemta.com/llms.txt) lists every page. [`/llms-full.txt`](https://docs.clemta.com/llms-full.txt) is the whole site in one file. Any of these can go in a `CLAUDE.md`, `AGENTS.md`, or `.cursorrules` file. ## Page menu The menu at the top of every page copies the page as Markdown, opens it in Claude or ChatGPT, connects the docs search server to Cursor or VS Code, and downloads the OpenAPI description. ## Agent instructions Every Markdown export, and both `llms` files, end with a short block of instructions: use a `clmt_test_` key while developing, send an `Idempotency-Key` on every write, pin `Clemta-Version`, and branch on error `code`. ## Skills A skill is a Markdown file an agent loads when the task matches its description. Skills are named `clemta--`, and the `clemta` skill is an index of all of them. One command installs the set: ```bash theme={null} npx skills add https://docs.clemta.com ``` The index is at [`/.well-known/agent-skills/index.json`](https://docs.clemta.com/.well-known/agent-skills/index.json) and each file at `/.well-known/agent-skills//SKILL.md`, for tools that read the agent-skills format directly. See [Partner API](/ai/partner-api) for what each skill covers. # Overview Source: https://docs.clemta.com/ai/introduction Connect an agent to Clemta, or let one build your integration. Agents meet Clemta in two places, for two different people. For people using the Clemta app, and for partner teams who would rather ask about a company than query for it. In development. For developers. Skills, a docs search server, Markdown pages, and llms.txt for the coding agent that writes your integration. ## By product Skills that carry the request rules and the sandbox, a starting prompt, and what to watch when an agent holds a key. ## Pick your path | You want to... | Go to | | ------------------------------------------------------ | ------------------------------------ | | Ask about a company from Claude or any MCP client | [Clemta MCP server](/ai/clemta-mcp) | | Let an agent read these docs from your editor | [Docs for agents](/ai/coding-agents) | | Have an agent write or debug a Partner API integration | [Partner API](/ai/partner-api) | # Partner API Source: https://docs.clemta.com/ai/partner-api Skills and a docs search server for the coding agent that writes your Partner API integration. Two skills cover the Partner API. Each is a Markdown file an agent loads when the task matches its description, and each names the other. | Skill | Covers | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `clemta-partner-quickstart` | Creating companies, ordering services, handling requirements, reading events. Includes the request rules: auth, idempotency, versioning, errors, and the sandbox. | | `clemta-partner-webhooks` | Writing or debugging a webhook handler: tunnel, simulate, verify, reconcile by polling. | Install both: ```bash theme={null} npx skills add https://docs.clemta.com ``` The full guide lives with the Partner API docs: connecting the docs search server, a starting prompt, and what to watch when an agent holds a key. # Advance your simulation clock Source: https://docs.clemta.com/api-reference/advance-clock /partner/openapi.yaml post /clock/advance Moves the mode's simulated time forward to `to` and runs the time-driven machinery up to it. Every renewal period that comes due before that moment bills, so a monthly order advanced a year bills twelve periods at once. A clock only moves forward, and at most five years in one call. Advancing changes nothing about how new records stamp their own times. It only decides how far "due" has looked. # Cancel a service order Source: https://docs.clemta.com/api-reference/cancel-service-order /partner/openapi.yaml delete /companies/{companyID}/service-orders/{orderID} Cancels an order still in `received` and credits back what you were billed. An order already in fulfilment cannot be reversed, but an ACTIVE RECURRING one takes a cancellation REQUEST instead: the call stamps `renewal_cancel_requested_at` and Clemta decides. Renewals keep billing until the request is approved. On approval the service runs to the end of the current period (`renewal_ends_at`) and is not billed again - except a product billed in arrears, whose running period still bills at its end, since it was served. You hear the outcome as `service_order.renewal_canceled` or `service_order.renewal_cancel_denied`. Fulfilment status is untouched. Cancelling again while a request is pending or decided is a no-op. A one-time order in fulfilment is refused with 409. # Create an account for a customer Source: https://docs.clemta.com/api-reference/create-account /partner/openapi.yaml post /accounts Creates an account - one of your end customers - that companies are then created under. The customer receives no messages from Clemta. Pass `Idempotency-Key` to make retries safe. # Create your simulation clock Source: https://docs.clemta.com/api-reference/create-clock /partner/openapi.yaml post /clock Opens the clock for the calling key's mode, frozen at the real current time. One clock exists per mode, so creating again returns the existing clock unchanged. While the clock exists, advancing it runs the renewals that come due on your companies forward, so you can test recurring billing without waiting for real time. Deleting it returns the mode to real time. # Create a customer company Source: https://docs.clemta.com/api-reference/create-company /partner/openapi.yaml post /companies Creates a customer and a company shell attributed to you. The customer receives no messages from Clemta. Pass `Idempotency-Key` to make retries safe. # Upload a file Source: https://docs.clemta.com/api-reference/create-file /partner/openapi.yaml post /files Upload a file to attach elsewhere by id. Send `multipart/form-data` with a `file` part and a `purpose`. `identity_document` uploads are an owner's passport or government ID: attach one to a `document` requirement (`document` on fulfill) or directly at company create (`shareholders[].passport`). `additional_document` uploads answer a form's file field: pass the file id as that field's value on fulfill. Uploads are single-use and write-only - the response carries no download URL and the contents can never be read back through the API. Each purpose sets its own accepted types, size ceiling and file count (PDF, JPEG or PNG and 10MB for documents, smaller for branding images). Content is verified against the declared type. # Create a file link Source: https://docs.clemta.com/api-reference/create-file-link /partner/openapi.yaml post /file-links Mints a public URL over one of your files: anyone holding the URL can read the contents without authentication, until the link expires. Only shareable files can be linked - Clemta deliverables and branding uploads. A customer identity document is refused. # Add a fixed asset Source: https://docs.clemta.com/api-reference/create-fixed-asset /partner/openapi.yaml post /companies/{companyID}/fixed-assets Adds a fixed asset to the company's register. It is assigned the next `AST-` number. A later federal tax filing snapshots the register, so an asset added here reaches the filing. # Add an officer or director Source: https://docs.clemta.com/api-reference/create-officer /partner/openapi.yaml post /companies/{companyID}/officers Seats an officer on the company's roster with the roles given. An officer whose `email` matches a shareholder's is seated as that owner. For a company already handed off to Clemta, the change reaches Clemta. The roles are validated against the entity type (LLC vs C-Corp catalogues). # Simulate an event (test keys only) Source: https://docs.clemta.com/api-reference/create-sandbox-simulation /partner/openapi.yaml post /sandbox/companies/{companyID}/simulate Moves a test company - or one of its orders, tax filings or documents - the way a live change would, and delivers the resulting event(s) to your test webhooks. Available only with a test key (`clmt_test_`). A live key is refused. Nothing reaches Clemta. The response is the company afterwards. # Attach a service to a company Source: https://docs.clemta.com/api-reference/create-service-order /partner/openapi.yaml post /companies/{companyID}/service-orders Orders a product against the company and bills you for it at creation, at your wholesale price. Idempotent - re-attaching the same product returns the existing order and does not bill you twice. Pass `Idempotency-Key` for safe retries. # Create a hosted signing session Source: https://docs.clemta.com/api-reference/create-signing-session /partner/openapi.yaml post /companies/{companyID}/signing-sessions Mints a fresh hosted signing URL for one open signature requirement. Live mode only, and your hosted page must be configured - the page presents your brand and legal links while collecting a signature. # Create an end-customer status link Source: https://docs.clemta.com/api-reference/create-status-token /partner/openapi.yaml post /companies/{companyID}/status-tokens Mints a read-only status link for the company and returns its URL. Hand the URL to your customer. Anyone holding it can read the company's live status - progress only, no documents, no personal data, no prices - by calling GET /status/{token}, so you can drive a progress view in your own product without sharing your API key. Multiple links per company are allowed, each individually revocable. The URL is shown once. # Open a tax filing Source: https://docs.clemta.com/api-reference/create-tax-filing /partner/openapi.yaml post /companies/{companyID}/tax-filings Opens a federal or state filing for the current year. One filing per company, type and year. Identity fields prefill from the company. Opening is free - the filing entitlement is spent when the filing is submitted - so a draft can sit as long as it needs to. Pass `submit: true` with a complete form to open and submit in one atomic call. # Create a hosted verification session Source: https://docs.clemta.com/api-reference/create-verification-session /partner/openapi.yaml post /companies/{companyID}/verification-sessions Mints a fresh URL for the hosted identity-document page, for one owner of this company. Live mode only - the hosted page collects a real identity document. Test companies rehearse verification through the sandbox simulate endpoint instead. Requires the verification page to be configured first (your display name and privacy policy - the page presents them to your customer). Refused when the owner's document is already received. # Delete your simulation clock Source: https://docs.clemta.com/api-reference/delete-clock /partner/openapi.yaml delete /clock Removes the mode's clock. The simulated world returns to real time. Nothing already billed is undone - periods the clock advanced over stay billed, and renewal dates advanced into the future are simply not due yet. # Delete a fixed asset Source: https://docs.clemta.com/api-reference/delete-fixed-asset /partner/openapi.yaml delete /companies/{companyID}/fixed-assets/{fixedAssetID} # Remove an officer or director Source: https://docs.clemta.com/api-reference/delete-officer /partner/openapi.yaml delete /companies/{companyID}/officers/{officerID} Removes the officer from the roster. # Fulfill a requirement Source: https://docs.clemta.com/api-reference/fulfill-requirement /partner/openapi.yaml post /requirements/{requirementID}/fulfill Resolve an open requirement with its answers - a `form`, `name_change` or `information` requirement with `values`, a `document` requirement with an uploaded file by id (`document`, or `documents` for several pages). Emits `requirement.fulfilled`. # Fetch an account Source: https://docs.clemta.com/api-reference/get-account /partner/openapi.yaml get /accounts/{accountID} # Read your simulation clock Source: https://docs.clemta.com/api-reference/get-clock /partner/openapi.yaml get /clock The clock for the calling key's mode, or 404 when none exists. The clock is a sandbox tool - live keys are refused. Use a test key. # Retrieve a company Source: https://docs.clemta.com/api-reference/get-company /partner/openapi.yaml get /companies/{companyID} # Retrieve a file Source: https://docs.clemta.com/api-reference/get-file /partner/openapi.yaml get /files/{fileID} # Download a file's bytes Source: https://docs.clemta.com/api-reference/get-file-content /partner/openapi.yaml get /files/{fileID}/contents Streams the document itself. The response's Content-Type is the file's own. Content-Disposition carries the filename. # Retrieve a file link Source: https://docs.clemta.com/api-reference/get-file-link /partner/openapi.yaml get /file-links/{linkID} # Read a file link's contents Source: https://docs.clemta.com/api-reference/get-file-link-contents /partner/openapi.yaml get /file-links/{token}/contents The public door a file link's `url` points at: streams the file's bytes with no authentication - the token in the path is the credential. An unknown or expired token answers 404. # Retrieve a fixed asset Source: https://docs.clemta.com/api-reference/get-fixed-asset /partner/openapi.yaml get /companies/{companyID}/fixed-assets/{fixedAssetID} # Identify the calling API key Source: https://docs.clemta.com/api-reference/get-me /partner/openapi.yaml get /me Returns the partner and mode the presented key resolves to. # Retrieve a requirement Source: https://docs.clemta.com/api-reference/get-requirement /partner/openapi.yaml get /requirements/{requirementID} One requirement. An open `form` requirement carries the live `form` schema - the fields to collect next. # Read a hosted link's context Source: https://docs.clemta.com/api-reference/get-requirement-link-context /partner/openapi.yaml get /requirement-links/{token} What the hosted page renders: what is asked and of whom, plus your hosted-page branding. Authenticated by the token itself - no API key. # Retrieve a service order Source: https://docs.clemta.com/api-reference/get-service-order /partner/openapi.yaml get /companies/{companyID}/service-orders/{orderID} # Read a signing link Source: https://docs.clemta.com/api-reference/get-signing-link-context /partner/openapi.yaml get /signing-links/{token} What the hosted signing page renders - the ask, the partner's branding and the embedded signing session. Authenticated by the token itself, no API key. The signature itself completes inside the embedded session. The requirement resolves once the signature completes, and the page only ever reads. # Read a company's status by its link token Source: https://docs.clemta.com/api-reference/get-status /partner/openapi.yaml get /status/{token} The end customer's read-only status, resolved from the status token in the path - no API key. Returns only progress as JSON: no documents, no personal data, no prices. Use it to drive a progress view in your own product. # Retrieve a tax filing Source: https://docs.clemta.com/api-reference/get-tax-filing /partner/openapi.yaml get /companies/{companyID}/tax-filings/{filingID} The filing with its questionnaire and readiness. The form reads live, so the latest changes are visible immediately. # List your accounts - sortable, cursor-paged Source: https://docs.clemta.com/api-reference/list-accounts /partner/openapi.yaml get /accounts Your accounts, newest first. Sortable by `created_at`. # List your companies - filterable, sortable, cursor-paged Source: https://docs.clemta.com/api-reference/list-companies /partner/openapi.yaml get /companies Sort by `created_at` or `name`. Filter by any company field, `external_id` and `state` included. # List a company's compliance calendar Source: https://docs.clemta.com/api-reference/list-company-calendar /partner/openapi.yaml get /companies/{companyID}/calendar The company's upcoming compliance items - annual report and tax deadlines - soonest first. A `calendar.reminder` webhook fires ahead of each one, so you can notify your customer under your own brand. Test-mode companies carry no calendar and answer an empty list. # List a company's documents Source: https://docs.clemta.com/api-reference/list-company-files /partner/openapi.yaml get /companies/{companyID}/files Every document Clemta has published on the company, newest first - formation deliverables, filed forms, letters. `file.created` announces each new one. # List a company's tax filings Source: https://docs.clemta.com/api-reference/list-company-tax-filings /partner/openapi.yaml get /companies/{companyID}/tax-filings Every federal and state filing opened on the company, newest year first, with its review status and progress. Each filing is opened by you or your customer against the company's `entitlements`. Read them here. # List your event stream - newest first, cursor-paged Source: https://docs.clemta.com/api-reference/list-events /partner/openapi.yaml get /events Filter by `type`, `company_id`, or a `created_at` range. Sortable by `created_at`. # List all file links Source: https://docs.clemta.com/api-reference/list-file-links /partner/openapi.yaml get /file-links Your file links, newest first. Filter by `file`. # List all files Source: https://docs.clemta.com/api-reference/list-files /partner/openapi.yaml get /files Every file in your account, newest first - Clemta-published deliverables and your own uploads alike. Filter by `purpose`, `source` or `company`. # List a company's fixed assets Source: https://docs.clemta.com/api-reference/list-fixed-assets /partner/openapi.yaml get /companies/{companyID}/fixed-assets The company's fixed-asset register. The federal tax filing draws from these. # List a company's officers and directors Source: https://docs.clemta.com/api-reference/list-officers /partner/openapi.yaml get /companies/{companyID}/officers The company's management roster. A director is an officer holding role `director`. There is no separate directors list. # List the products you can offer, at your prices Source: https://docs.clemta.com/api-reference/list-products /partner/openapi.yaml get /products Your catalog with your wholesale price on each line - your override where you have one, the default otherwise. These keys are what you pass as `product_key` when you attach a service order. # List requirements Source: https://docs.clemta.com/api-reference/list-requirements /partner/openapi.yaml get /requirements Everything currently (or previously) needed from you, newest first. Filter by company and/or status. Poll `status=open` to see what is outstanding. # List a company's service orders Source: https://docs.clemta.com/api-reference/list-service-orders /partner/openapi.yaml get /companies/{companyID}/service-orders # List a company's status links Source: https://docs.clemta.com/api-reference/list-status-tokens /partner/openapi.yaml get /companies/{companyID}/status-tokens # Preview what creating a company would bill Source: https://docs.clemta.com/api-reference/preview-company-basket /partner/openapi.yaml post /companies/price-preview Resolve the whole basket a company create would charge - the formation with its state filing fee, every mandatory service the profile auto-attaches, and every service you list - WITHOUT creating anything. Priced by the same resolution the create runs, so it cannot quote a total the create does not charge. Each line carries its own interval, and the lines are not summed. Amounts are estimates - the create resolves again and freezes what it billed. # Preview a product's price for an existing company Source: https://docs.clemta.com/api-reference/preview-company-product-price /partner/openapi.yaml get /companies/{companyID}/products/{productKey}/price-preview Resolve what a product would bill for THIS company, read from the company's own attributes - no profile query params to state or get wrong. It resolves against the same facts the order does (entity type, state, owner count, whether it holds an EIN, whether it is incorporated), so it cannot quote a price the order would not charge. Returns your own amount (override, matching price rule, or default - `applied_rule` says which), each option value's effective amount, and every pass-through government or state fee line at today's amounts. Use `GET /products/{productKey}/price-preview` instead to price a product for a hypothetical company before one exists. # Preview every line an order would bill Source: https://docs.clemta.com/api-reference/preview-product-price /partner/openapi.yaml get /products/{productKey}/price-preview Resolve one product for a company profile BEFORE creating anything: your own amount (override, matching price rule, or default - `applied_rule` says which), each option value's effective amount, and every pass-through government or state fee line at today's amounts. Use it to price your own offer with no surprises. The order itself resolves again and freezes what it billed on the order's `fees`. Formation keys also carry the state's filing fee. # Upload the document set through a hosted link Source: https://docs.clemta.com/api-reference/put-requirement-link-document /partner/openapi.yaml put /requirement-links/{token}/document The hosted page's upload: the link URL itself is the credential - a time-limited, single-purpose capability, no API key. Send the COMPLETE document set in one request: `multipart/form-data` with one part per page (a two-sided ID is two parts), or the raw bytes of a single file with its Content-Type. The request itself is completeness - there is no add-another-page call. Validation: PDF, JPEG and PNG only, at most 10 MB per file, at most 2 files, and the bytes must actually be the format the Content-Type declares (file signatures are checked) - a mislabeled file is refused with `invalid_request`. # Revoke a status link Source: https://docs.clemta.com/api-reference/revoke-status-token /partner/openapi.yaml delete /companies/{companyID}/status-tokens/{tokenID} Kills the link everywhere within seconds. # Submit a tax filing Source: https://docs.clemta.com/api-reference/submit-tax-filing /partner/openapi.yaml post /companies/{companyID}/tax-filings/{filingID}/submit Submits the filing to Clemta for review. This is the one transactional moment - readiness is checked, one filing entitlement is spent, and the filing moves to `in_review`, all together or not at all. A filing already submitted answers its current state, so a retry is a no-op. With no entitlement remaining the draft stays intact - order the matching entitlement product and retry. # Supply a signer's email Source: https://docs.clemta.com/api-reference/supply-signer-email /partner/openapi.yaml post /companies/{companyID}/signature-signers Provides the email for a deferred signer - one Clemta opened with a name but no email (status `pending_email`). Once every signer on the document has an email, the signing round opens for all of them and you can mint their sessions. Live mode only. The email is not required to be one of the company's owners. A deferred signer is an outside party by design. # Update an account's metadata Source: https://docs.clemta.com/api-reference/update-account /partner/openapi.yaml post /accounts/{accountID} # Update a company Source: https://docs.clemta.com/api-reference/update-company /partner/openapi.yaml post /companies/{companyID} # Update a file link Source: https://docs.clemta.com/api-reference/update-file-link /partner/openapi.yaml post /file-links/{linkID} Moves the expiry or replaces the metadata. Set `expires_at` to the literal `now` to expire the link immediately - the way to revoke a URL that is already in someone's hands. # Update a fixed asset Source: https://docs.clemta.com/api-reference/update-fixed-asset /partner/openapi.yaml post /companies/{companyID}/fixed-assets/{fixedAssetID} Sparse update - a field left out is unchanged. # Update an officer or director Source: https://docs.clemta.com/api-reference/update-officer /partner/openapi.yaml post /companies/{companyID}/officers/{officerID} Replaces the officer's roles and identity. Send the full desired state. The roles are validated against the entity type. # Upgrade a service order's options Source: https://docs.clemta.com/api-reference/update-service-order /partner/openapi.yaml post /companies/{companyID}/service-orders/{orderID} Changes an in-flight order's variant choices and bills you the price DIFFERENCE - for example moving an `ein` order's `processing` from `standard` to `expedited` after the fact. Only upgrades are accepted (the new choice must not price below the current one), the order must not be completed or canceled, and the product's `available_when` must still hold for the company as it stands now - an ein upgrade is refused once the company's EIN is recorded. One upgrade may stand at a time. Choices that add a companion service attach it automatically. # Update a tax filing Source: https://docs.clemta.com/api-reference/update-tax-filing /partner/openapi.yaml post /companies/{companyID}/tax-filings/{filingID} Replaces the provided form sections on a draft. A section you send replaces the stored one whole, a section you omit stays as it is. Only a draft is editable - after submit, changes go through Clemta. # Calendar reminder Source: https://docs.clemta.com/api-reference/webhooks/calendar-reminder /partner/openapi.yaml webhook calendar.reminder Sent ahead of a company's compliance calendar deadline, once per reminder point. No mail is sent to your customer - relay the reminder under your own brand. `data.object` is the calendar event with `due_at` and the `remind_at` that fired. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Company created Source: https://docs.clemta.com/api-reference/webhooks/company-created /partner/openapi.yaml webhook company.created Sent to your configured endpoint when a company is created through the API, in either mode (a `clmt_test_` key's events carry `livemode: false`). The request body is the `event` resource. Fetch the company it names for its current state. Verify the `Clemta-Webhook-Signature` header with your endpoint's signing secret before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Company dissolved Source: https://docs.clemta.com/api-reference/webhooks/company-dissolved /partner/openapi.yaml webhook company.dissolved Sent exactly once, when a dissolution order completes and the company reaches its terminal `dissolved` status. Every recurring service on the company stops renewing at that moment, open requirements are closed, and nothing further can be ordered to it. The request body is the `event` resource, whose `data.object` is the company as of the dissolution. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Company document received Source: https://docs.clemta.com/api-reference/webhooks/company-document-received /partner/openapi.yaml webhook company.document.received Sent when an individual owner uploads their identity document. The request body is the `event` resource. Fetch the company it names to see which owners are still outstanding. When the last document lands, the company also emits `company.status.changed`. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Company ein assigned Source: https://docs.clemta.com/api-reference/webhooks/company-ein-assigned /partner/openapi.yaml webhook company.ein.assigned Sent once, when the IRS issues the company's federal tax id and Clemta records it. The payload carries `ein`. The request body is the `event` resource. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Company entitlements changed Source: https://docs.clemta.com/api-reference/webhooks/company-entitlements-changed /partner/openapi.yaml webhook company.entitlements.changed Sent when the company's `entitlements` move - a tax-filing credit added by an order or by Clemta, or consumed by a filing. `data.object` is the company with its current `entitlements`. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Company incorporated Source: https://docs.clemta.com/api-reference/webhooks/company-incorporated /partner/openapi.yaml webhook company.incorporated Sent once, when the state accepts the filing and the company becomes active - the milestone to tell your customer about. `company.status.changed` fires as well. This event exists so the moment is a single, unmistakable signal. The request body is the `event` resource. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Company name changed Source: https://docs.clemta.com/api-reference/webhooks/company-name-changed /partner/openapi.yaml webhook company.name.changed Sent when Clemta changes the company's legal name - typically to clear a conflict with the state. The payload carries the new name. Update your own records and tell your customer. The request body is the `event` resource. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Company onboarding completed Source: https://docs.clemta.com/api-reference/webhooks/company-onboarding-completed /partner/openapi.yaml webhook company.onboarding.completed Sent once, when Clemta finishes taking a pre_existing company onto the platform - the moment a newly formed company would instead announce `company.incorporated`. A company incorporated years before it arrived never fires the incorporation event. This is its counterpart milestone. `data.object` is the company. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Company status changed Source: https://docs.clemta.com/api-reference/webhooks/company-status-changed /partner/openapi.yaml webhook company.status.changed Sent when a company moves between formation states. The request body is the `event` resource. Branch on the company's status after fetching it rather than on the event type alone. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Company updated Source: https://docs.clemta.com/api-reference/webhooks/company-updated /partner/openapi.yaml webhook company.updated Sent when Clemta edits the company's identity - entity type, state, industry, share structure, formation date, legal address or the owner roster. `data.object` is the company as it now stands. Verify the `Clemta-Webhook-Signature` header before trusting the payload. # Company verified Source: https://docs.clemta.com/api-reference/webhooks/company-verified /partner/openapi.yaml webhook company.verified Sent once, when the last owner's identity document lands and the company is ready for formation - well before incorporation (which has its own event, `company.incorporated`). Verification never regresses. The request body is the `event` resource. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # File created Source: https://docs.clemta.com/api-reference/webhooks/file-created /partner/openapi.yaml webhook file.created Sent when Clemta publishes a document on one of your companies. The request body is the `event` resource whose `data.object` is the file. Download the bytes from the file's content endpoint. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Invoice finalized Source: https://docs.clemta.com/api-reference/webhooks/invoice-finalized /partner/openapi.yaml webhook invoice.finalized Sent when your month-end wholesale invoice is raised. The request body is the `event` resource, whose `data.object` is the invoice. It is collected automatically from your payment method on file. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Requirement canceled Source: https://docs.clemta.com/api-reference/webhooks/requirement-canceled /partner/openapi.yaml webhook requirement.canceled Sent when an open requirement closes WITHOUT being fulfilled - a signer declining a signature request, or Clemta withdrawing the ask. The request body is the `event` resource whose `data.object` is the requirement. Its `cancel_reason` says why, in words safe to show your customer. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Requirement created Source: https://docs.clemta.com/api-reference/webhooks/requirement-created /partner/openapi.yaml webhook requirement.created Sent when a requirement opens: an owner's identity document, a service-order form, or something Clemta asked for (a company-name change, extra information). The request body is the `event` resource whose `data.object` is the requirement. Fulfill it over the API or hand your customer a hosted link. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Requirement fulfilled Source: https://docs.clemta.com/api-reference/webhooks/requirement-fulfilled /partner/openapi.yaml webhook requirement.fulfilled Sent when an open requirement resolves - by your API call or by your customer through a hosted link. The request body is the `event` resource whose `data.object` is the requirement with its response. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Requirement signature signed Source: https://docs.clemta.com/api-reference/webhooks/requirement-signature-signed /partner/openapi.yaml webhook requirement.signature.signed Sent when one signer completes their part of a signature document. A document with several signers fires this once per signer. The requirement itself resolves (requirement.fulfilled) only when the last of them signs. The request body is the `event` resource whose `data.object` is the requirement with its `signers`. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Requirement signature viewed Source: https://docs.clemta.com/api-reference/webhooks/requirement-signature-viewed /partner/openapi.yaml webhook requirement.signature.viewed Sent the first time a signer opens the signature document. A requirement with several signers fires this once per signer. The request body is the `event` resource whose `data.object` is the requirement with its `signers`. Progress only - the document is not signed yet. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Service order completed Source: https://docs.clemta.com/api-reference/webhooks/service-order-completed /partner/openapi.yaml webhook service_order.completed Sent exactly once per order, the first time it reaches `completed` - `completed_at` is set then and never cleared, and a later status echo does not repeat it. The request body is the `event` resource, whose `data.object` is the completed service order. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Service order quoted Source: https://docs.clemta.com/api-reference/webhooks/service-order-quoted /partner/openapi.yaml webhook service_order.quoted Sent when Clemta set the price on a quote_pending order - a product priced per piece of work, such as catch-up bookkeeping. The request body is the `event` resource, whose `data.object` is the service order carrying its `quote` object: the amount, and `expires_at`, the acceptance window. Accept with `accept_quote: true` on the order update endpoint before the window lapses. Nothing is billed until you do, and cancelling the order declines the quote. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Service order renewal cancel denied Source: https://docs.clemta.com/api-reference/webhooks/service-order-renewal-cancel-denied /partner/openapi.yaml webhook service_order.renewal_cancel_denied Sent when Clemta denies your cancellation request on a recurring order. The request is cleared and the order keeps renewing as before - contact support for the reasoning. The request body is the `event` resource, whose `data.object` is the service order as of the decision. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Service order renewal canceled Source: https://docs.clemta.com/api-reference/webhooks/service-order-renewal-canceled /partner/openapi.yaml webhook service_order.renewal_canceled Sent when Clemta approves your cancellation request on a recurring order. The service runs to `renewal_ends_at` and is not billed past it - except a product billed in arrears, whose running period still bills at that moment, since it was served. The request body is the `event` resource, whose `data.object` is the service order as of the approval. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Service order status changed Source: https://docs.clemta.com/api-reference/webhooks/service-order-status-changed /partner/openapi.yaml webhook service_order.status.changed Sent when a service order is created or its fulfilment status changes, including cancellation. The request body is the `event` resource, whose `data.object` is the service order as of the change. Branch on its status rather than on the event type alone. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Service order updated Source: https://docs.clemta.com/api-reference/webhooks/service-order-updated /partner/openapi.yaml webhook service_order.updated Sent when an order's options or price change without you calling - today, Clemta reversing an options upgrade it could not deliver: the difference you were billed is credited back and the order returns to its previous choices and price. The request body is the `event` resource, whose `data.object` is the order as of the change. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge - a non-2xx or a timeout is retried with backoff. # Tax filing created Source: https://docs.clemta.com/api-reference/webhooks/tax-filing-created /partner/openapi.yaml webhook tax_filing.created Sent when a federal or state tax filing is opened on the company. `data.object` is the tax filing. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Tax filing status changed Source: https://docs.clemta.com/api-reference/webhooks/tax-filing-status-changed /partner/openapi.yaml webhook tax_filing.status.changed Sent when Clemta moves a tax filing's `status` or `progress`. `data.object` is the tax filing as of the change. Branch on its fields. Verify the `Clemta-Webhook-Signature` header before trusting the payload, and respond with any 2xx to acknowledge. # Build with an AI agent Source: https://docs.clemta.com/partner/ai-agents Let a coding agent write the integration, and let your team ask an agent about the companies behind it. Agents help on two sides of the Partner API. A coding agent writes and debugs the integration, if it has the contract. Everything below hands it over, and none of it needs a key. Once companies are in Clemta, your team can ask an agent about them instead of opening a dashboard. That part is at the [end of this page](#not-just-for-code). ## Skills Two skills cover the Partner API. Each is a Markdown file an agent loads when the task matches its description, and each names the other. | Skill | Covers | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `clemta-partner-quickstart` | Creating companies, ordering services, handling requirements, reading events. Includes the request rules: auth, idempotency, versioning, errors, and the sandbox. | | `clemta-partner-webhooks` | Writing or debugging a webhook handler: tunnel, simulate, verify, reconcile by polling. | Install both: ```bash theme={null} npx skills add https://docs.clemta.com ``` ## Docs search A search server for these docs runs at `https://docs.clemta.com/mcp`. Connect it and the agent looks things up here as it works. It searches the docs and does not call the API. ```bash Claude Code theme={null} claude mcp add --transport http clemta-docs https://docs.clemta.com/mcp ``` ```json Cursor (.cursor/mcp.json) theme={null} { "mcpServers": { "clemta-docs": { "url": "https://docs.clemta.com/mcp" } } } ``` ```json VS Code (.vscode/mcp.json) theme={null} { "servers": { "clemta-docs": { "type": "http", "url": "https://docs.clemta.com/mcp" } } } ``` The **Connect** entries in the menu at the top of every page do the same in one click. ## Markdown, llms.txt, and the spec * Add `.md` to any page URL for its Markdown: `https://docs.clemta.com/partner/webhooks.md`. * [`/llms.txt`](https://docs.clemta.com/llms.txt) lists every page. [`/llms-full.txt`](https://docs.clemta.com/llms-full.txt) is the whole site in one file. * The OpenAPI description is served from the API without a key: `https://api.clemta.com/v1/openapi.json`. See [OpenAPI specs](/partner/openapi-specs) for the dated URLs. Any of these can go in a `CLAUDE.md`, `AGENTS.md`, or `.cursorrules` file. ## A starting prompt With a skill or the docs server connected: ```text theme={null} Integrate the Clemta Partner API. Use my clmt_test_ key from CLEMTA_API_KEY. Create a company for a customer, expose a webhook handler that verifies signatures, and move the test company to active with the sandbox so I can see company.incorporated arrive. ``` ## When an agent holds a key * The key sets the mode. A `clmt_test_` key never reaches live objects, and `/sandbox/*` refuses live keys. Give an agent a live key only when it should act on real companies. * Keep keys in an environment variable or the agent's secret store. Never put one in a prompt, a skill file, or a committed file. * Send an `Idempotency-Key` on every write. An agent that retries a timed-out `POST /companies` without one forms two companies. * When a request fails with `invalid_request`, the `errors` array names every field. Pass that list to the agent. A blind retry fails the same way. ## Not just for code Once a company is in Clemta, your team can ask about it in plain words. An operations lead connects Claude, Cursor, or any MCP client to the [Clemta MCP server](/ai/clemta-mcp) with a Partner API key and asks: which companies are waiting on a document, what stage an order is at, when a filing is due. The answers come from the same objects your integration works with. The server is in development. ## Where the skills come from The skills are written from these guides and stay in step with them: [Quickstart](/partner/quickstart), [How it fits together](/partner/concepts), [Idempotency](/partner/idempotency), [Versioning](/partner/versioning), [Errors](/partner/errors), [Webhooks](/partner/webhooks), and [Local development](/partner/local-development). For everything agent-related across Clemta, see [AI agents](/ai/introduction). # Authentication Source: https://docs.clemta.com/partner/authentication API keys: the four kinds, what a restricted key can do, rotation, IP allowlists, and the error shape. The Partner API authenticates with a bearer key. Send it in the `Authorization` header on every request: ``` Authorization: Bearer clmt_live_9f2aK4dQ8xR3mB1nT7cV ``` ## Keys Keys are issued from the [partner dashboard](/partner/dashboard), not through public signup. The prefix tells you the mode and the reach of a key at a glance: | Prefix | Mode | Reach | | --------------- | ------------------------------------------ | ------------------------------------ | | `clmt_live_` | Live: real companies, real billing. | Everything. | | `clmt_test_` | Test: a sandbox that creates nothing real. | Everything. | | `clmt_rk_live_` | Live. | Only the scopes it was created with. | | `clmt_rk_test_` | Test. | Only the scopes it was created with. | The raw key is shown once, at creation, and never again. Store it before you leave the page. Any member of your workspace can create a test key. Live keys are created by the workspace owner. ## Restricted keys A key created with scopes is restricted to them. A scope is a resource and an action, `resource:action`. Write includes read. | Scope | Reaches | | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `companies:read` / `companies:write` | Companies and everything on them: service orders, requirements, verification and signing sessions, status tokens, files and file links, tax filings, calendar, fixed assets, officers, the sandbox and the test clock. | | `accounts:read` / `accounts:write` | Accounts. | | `events:read` | `GET /events`. | | `*:read` / `*:write` | Every resource, at that action. | A restricted key that reaches for something outside its scopes is refused with [`insufficient_scope`](/partner/errors#insufficient_scope). A few endpoints need no scope at all and answer any valid key: [`GET /me`](/api-reference/get-me), [`GET /products`](/api-reference/list-products), and the price previews. Webhook endpoints are managed from the dashboard only, so no scope covers them. ## Rotating a key Rotate from the dashboard when a key may have leaked, or on a schedule. Rotation issues a new key and keeps the old one working for a grace window. The window is 24 hours by default and can be anything up to 7 days, so you can move your services over one at a time. Set it to zero to cut the old key off at once. After the window, the old key answers [`api_key_expired`](/partner/errors#api_key_expired). Revoking a key stops it immediately, with no grace. ## IP allowlist A key can be limited to a set of IP addresses or CIDR ranges, up to 100. A request from anywhere else is refused with [`ip_address_not_allowed`](/partner/errors#ip_address_not_allowed). An empty list means the key works from anywhere. The allowlist is set per key, by the workspace owner. ## Confirming sensitive actions Rotating or revoking a key, changing an allowlist, and rolling a webhook secret each ask for a six-digit code emailed to you. A code lasts ten minutes and five wrong attempts void it. One confirmation covers further sensitive actions for the next five minutes. ## Errors A missing, malformed, or revoked key is answered `401` with the standard error envelope (see [Errors](/partner/errors)): ```json theme={null} { "type": "https://docs.clemta.com/partner/errors#api_key_invalid", "title": "Invalid API key", "status": 401, "code": "api_key_invalid", "detail": "the Authorization header is missing or malformed", "request_id": "req_0348iOz07EPWoBXa6JZO0Z" } ``` Branch on `code`, never on `detail`. The wording may change. ## Example ```bash curl theme={null} curl https://api.clemta.com/v1/me \ -H "Authorization: Bearer clmt_live_9f2aK4dQ8xR3mB1nT7cV" ``` ```typescript fetch theme={null} await fetch("https://api.clemta.com/v1/me", { headers: { Authorization: "Bearer clmt_live_9f2aK4dQ8xR3mB1nT7cV" }, }); ``` ```python requests theme={null} import requests requests.get( "https://api.clemta.com/v1/me", headers={"Authorization": "Bearer clmt_live_9f2aK4dQ8xR3mB1nT7cV"}, ) ``` # Billing Source: https://docs.clemta.com/partner/billing How you are charged: one billing account, wholesale prices, a charge per order, and one invoice a month. You have one billing account, and everything you sell is billed to it. There is no subscription and nothing to commit to up front. You pay wholesale prices, once a month, for what you ordered. ## What creates a charge | Moment | What lands on your ledger | | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | | A service order is created, or a company is created with `services[]` | One charge at the product's wholesale price. | | A recurring product renews | One charge per period, at the price captured on the order. A later price change never touches a running service. | | A quoted product is accepted | The quoted amount, at acceptance. Nothing before. | | An order in `received` is cancelled | A credit for the full charge. | | An options upgrade | The price difference. | A test key is never billed. Those moments still record on your test ledger, so you can rehearse them, but nothing in test mode is invoiced or counts toward a limit. ## One invoice a month At the end of each month, the charges and credits of that period roll into one statement. Once reviewed, it is issued as an invoice and collected automatically from the payment method on file. You hear it as [`invoice.finalized`](/api-reference/webhooks/invoice-finalized). The Billing page of your partner dashboard shows every invoice, each statement with its line-by-line breakdown, and a running usage ledger you can filter by company or product. ## Payment method Invoices are collected automatically, so a payment method has to be on file before you can sell in live mode. Without one, a live order is refused with [`billing_account_inactive`](/partner/errors#billing_account_inactive). Add or replace a card from the Billing page. If an invoice goes unpaid, the account moves to `past_due`. Nothing is removed and nothing stops running, but new live sales pause until the invoice is settled. ## Spending limits Some accounts carry a limit on unbilled charges, shown on your Billing page. When the month's charges reach it, new live sales are refused until the next invoice is paid. Prepaid accounts work the other way around: you top up in advance and sell against the balance. ## Prices [`GET /products`](/api-reference/list-products) lists every product at your wholesale price, in the currency's smallest unit. Preview what a company or a product would cost before ordering with the price-preview endpoints. Your price sheet, and any negotiated rates on it, live on the Pricing page of the dashboard. # Changelog Source: https://docs.clemta.com/partner/changelog Dated changes to the Partner API The Partner API is versioned by date. See [Versioning](/partner/versioning) for how to pin a version, and [API versions](/partner/versions) for the versions you can pin today. Release notes land here once the API is generally available. # Company lifecycle Source: https://docs.clemta.com/partner/company-lifecycle Company statuses, formation stages, identity documents, and the events that mark each step from POST /companies to an incorporated entity with an EIN. ## Creating a company [`POST /companies`](/api-reference/create-company) takes the entity (name, state, type, ending, industry, shares), its owners, the customer it belongs to, and optionally the services to attach at the same time. Everything lands in **one transaction**: the account (if created inline), the company, its service orders, the charges, and the [`company.created`](/api-reference/webhooks/company-created) event - all or nothing. ### Input rules The API validates every field server-side: * **`name`** - IRS naming rules: letters, numbers, spaces, `-` and `&` only, and never a leading "The". The suffix is the separate `ending` field. `name_style: comma` renders "Acme, LLC" and the company returns the assembled `legal_name` read-only. * **`state`** - any of the 50 states or DC, as a two-letter code. * **`owner_privacy`** - `public` (default) or `private`: whether the owners are kept off the public filing. It is the customer's choice, and only the states that offer it accept `private` (DE, NV, WY, NM). * **`ending`** is an API token and must match the entity type. LLC: `llc`, `l_l_c`, `limited_liability_company`. C-Corp: `inc`, `incorporated`, `co`, `corp`, `corporation`. The rendered legal text ("L.L.C.", "Inc.") appears in `legal_name`. * **`industry`** is one of the platform catalog's 36 tokens (`accounting` ... `transportation`, plus `other`). An unknown value is rejected with a did-you-mean suggestion. `other` requires both `custom_industry` (the custom industry's short name) and `industry_description` (the free-text description). Every other value refuses both. * **Owners** - each individual or company owner needs email, phone, a title and a complete address (filing charset: letters, numbers and `& . , : ; ' # -`). `tax_id` is validated and normalized to the standard masks: `123-45-6789` (ssn/itin), `12-3456789` (ein). Ownership must total 100 with exactly one representative, and every named owner's `percent_ownership` must be above 0. * **Owner text fields** - `first_name` and `last_name` take English letters and spaces only. A company owner's `name` and `representative_name` take letters, numbers, spaces and `& . , -`. `email` must be a valid address. `phone_country` (optional) is an ISO 3166 alpha-2 code. * **Owner role** - `relationship.title` is a position token (`sole_owner`, `ceo` ... `operations_manager`, or `other`). `other` requires `custom_title` (filing charset), every other token refuses one. * **Owner identity** - no two owners may share an email or a tax id. * **`pre_existing` companies** - `address` is required (an existing company has a legal address by definition). `ein` and `foreign_qualifications[]` stay optional. All three are rejected on companies Clemta forms. The incorporation date is never an input: a `formation_document` requirement opens at creation, your customer uploads the formation document, and Clemta reads the date off it before onboarding completes. * **Shares and units** - a **C-Corp** declares `authorized_shares` and `par_value` (both required), and each owner's `percent_ownership` must resolve to a whole number of shares (33.4% of 1,000 shares works - 33.33% of 3 does not). An **LLC** has no share count to set: it is issued a fixed 100 membership units, so `authorized_shares` and `par_value` are not accepted on an LLC and are rejected if sent. * **Owners are optional at create.** Omit `shareholders`, or send `[]`, and supply them later before formation begins (see [Updating a company](#updating-a-company)). A company still needs its complete owner set, each owner's identity document included, before Clemta forms it. **An LLC's owners are its members.** The request field is `shareholders` for every entity type, but an LLC has no shareholders in law. Its owners are **members** holding membership units, and an LLC carries a `management_type` of `member_managed` or `manager_managed`. A C-Corp's `shareholders` are true shareholders holding shares. The field name is shared, the legal meaning follows the entity type, so read `shareholders` as "members" on an LLC. ```mermaid theme={null} sequenceDiagram participant P as Partner participant API as Clemta API participant C as Customer P->>API: POST /companies {owners, services[]} API-->>P: 201 company (status: requires_information) API-->>P: webhook company.created + requirement.created (per owner) P->>API: POST /companies/{id}/verification-sessions {shareholder} API-->>P: { url } for that owner's upload P->>C: hand off the upload url C->>API: upload identity document API-->>P: company.document.received Note over API: last document lands -> formation begins API-->>P: company.verified + company.status.changed (in_progress) API-->>P: company.status.changed (stage moves) API-->>P: company.incorporated + company.status.changed (active) API-->>P: company.ein.assigned ``` ### Updating a company [`POST /companies/{id}`](/api-reference/update-company) is a sparse update - send only the fields you want changed. What it accepts depends on where the company is: * **Before formation begins** (`status: requires_information`): the create-time details can still be corrected - `name`, `ending`, `name_style`, `industry` (+ `custom_industry`, `industry_description`), `authorized_shares`/`par_value`, the `shareholders` roster, and the `pre_existing`-only `ein`/`address`/`foreign_qualifications`. The create rules apply unchanged. * **The owner roster** is sent as a whole. `shareholders` **replaces** the entire roster, so include every owner on each update (an empty array clears it). This is how you add the owners a company was created without, or fix one before formation. Once formation begins the roster is Clemta's to change, and its edits reach you as [`company.updated`](/api-reference/webhooks/company-updated) - there is no per-owner add, edit, or remove endpoint on the API. * **Any time**: `timezone`, `owner_privacy`, `foreign_qualifications`, and `metadata`. Once formation has begun, a change to these is applied to the company and you receive [`company.updated`](/api-reference/webhooks/company-updated). * **Never**: `entity_type`, `state`, `pre_existing` - they price the formation. Cancel and create again instead. * **Cancelled is terminal**: only `metadata` can still be written on a cancelled company. Every other field answers `400`. A name change after incorporation is a state filing Clemta runs, not an API edit. The one API-answerable case is a `name_conflict` stage, resolved through the `name_change` requirement. Field changes fire `company.updated`. Metadata-only updates do not. An open requirement never moves `status` - the lifecycle stays the formation's own story. Instead the company carries a derived read-only **`open_requirements`** count on API reads: non-zero means something is waiting on you. Embed the open requirements themselves with `expand[]=requirements` (get and list alike), or list them with `GET /requirements?company={id}&status=open`, and follow them with [`requirement.created`](/api-reference/webhooks/requirement-created)/[`requirement.fulfilled`](/api-reference/webhooks/requirement-fulfilled) webhooks. ### `pre_existing`: did the company exist before? * `false` (default): Clemta forms the company. The formation itself is billed at your wholesale price, and products marked `required_for: ["formation"]` in your catalog attach automatically. * `true`: an already-formed company you are bringing in to offer services on. No formation is billed. Products marked `required_for: ["existing"]` attach automatically. Its `stage` still reports progress, from onboarding onward, and it reaches its milestone as [`company.onboarding.completed`](/api-reference/webhooks/company-onboarding-completed) rather than [`company.incorporated`](/api-reference/webhooks/company-incorporated) (a company formed years ago never re-incorporates). A pre-existing company may also bring its **`ein`** (stored `12-3456789` - [`company.ein.assigned`](/api-reference/webhooks/company-ein-assigned) never fires for a value you supplied), its legal **`address`**, and its **`foreign_qualifications`** - the other states it is registered in, each with the registered address there. All three are rejected on companies Clemta forms - Clemta sets them during fulfillment and they appear on the company as they become known. ### The account A company belongs to an **account** - your customer. Name an existing one with the `Clemta-Account` header, or send `account` details inline and it is created (or reused) for you. Accounts are unique per email within your workspace: inline details matching an existing account reuse it. Details that *disagree* with it are refused with `resource_already_exists`, so two different people can never be merged by accident. ## Status and stage `status` is the coarse lifecycle. `stage` is the fine-grained step within formation. ```mermaid theme={null} stateDiagram-v2 [*] --> requires_information: created requires_information --> in_progress: last owner document received in_progress --> in_progress: stage moves
preparing_documents -> documents_generated ->
signature_requested -> submitted_to_state in_progress --> active: state accepts the filing
(company.incorporated) in_progress --> cancelled active --> cancelled active --> dissolved: dissolution order completes ``` | status | Meaning | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `requires_information` | Waiting on you: identity documents for its owners are outstanding. Formation has not started. | | `in_progress` | Clemta is forming it. Watch `stage` for where. | | `active` | Incorporated. [`company.incorporated`](/api-reference/webhooks/company-incorporated) fired once, when `incorporated_at` was first set. The EIN follows as [`company.ein.assigned`](/api-reference/webhooks/company-ein-assigned). | | `cancelled` | Stopped or refunded. | | `dissolved` | The dissolution order completed: terminal. Recurring services stopped renewing, open requirements were closed, nothing further can be ordered. `dissolved_at` carries the moment, and [`company.dissolved`](/api-reference/webhooks/company-dissolved) announced it once. | `stage` values: `preparing_documents`, `documents_generated`, `signature_requested`, `submitted_to_state`, `name_conflict`, `incorporated`, `closed`. Each change fires [`company.status.changed`](/api-reference/webhooks/company-status-changed) with the full company embedded. ### When a company's details change Clemta may change a company's identity - entity type (even an LLC/C-CORP conversion), state, name suffix, industry, share structure, the legal `incorporation_date` and `address`, and the owner roster. Each such change fires **[`company.updated`](/api-reference/webhooks/company-updated)** with the company as it now stands. Owners keep their ids and uploaded documents through these edits. Name, EIN, status and incorporation keep their own dedicated events. ### Entitlements `entitlements` counts the rights the company holds - today federal and state tax filings (keys `federal_tax_filing`, `state_tax_filing`). They rise with an entitlement order or a grant from Clemta and fall when a filing is opened. [`company.entitlements.changed`](/api-reference/webhooks/company-entitlements-changed) announces each move. See [Service orders](/partner/service-orders#following-a-tax-filing). ### Milestones fire once Three events mark milestones rather than states, and each fires **exactly once** per company, when its timestamp is first set: [`company.verified`](/api-reference/webhooks/company-verified) (`verified_at`), `company.incorporated` (`incorporated_at`), and `company.ein.assigned` (`ein_assigned_at`). The timestamps are never cleared. A company whose status is later moved back to `active` fires `company.status.changed` for each move but does **not** incorporate again. A corrected EIN updates `ein` without a second `ein.assigned`. A `pre_existing` company reaches its milestone as [`company.onboarding.completed`](/api-reference/webhooks/company-onboarding-completed) instead of `company.incorporated`. Branch on the milestone events for one-time actions, and on `status`/`stage` for state. `verification` (`pending` / `verified`) is the owners' identity check. It is `pending` while any owner's document is outstanding and becomes `verified` the moment the last one lands and formation begins - the same instant `status` leaves `requires_information`. `company.verified` fires once there, well before incorporation, and the value never regresses. ## Identity documents Every owner needs an identity document before the company can be formed - an individual owner's own, a company owner's authorized representative's. At creation a `document` requirement opens per owner ([`requirement.created`](/api-reference/webhooks/requirement-created)), and that owner's `document.status` starts at `required`. An option pool, a share bucket with nobody behind it, needs none. If you already hold an owner's document, attach it at create instead: upload it through the [Files API](/partner/files) (purpose `identity_document`) and pass the file id as that owner's `passport`. The owner then arrives complete, with no `document` requirement or verification session opened for them. Each file id is single-use. For an owner whose document you do not yet hold, create a hosted verification session: ``` POST /companies/{id}/verification-sessions { "shareholder": "sh_..." } ``` It returns a short-lived `url`. The URL is the credential - it authorizes exactly that owner's document upload and nothing else. Hand it to your customer or open it from your own UI. Your customer uploads the file there with no API key (PDF, JPEG or PNG, up to 10 MB). Each upload fires [`company.document.received`](/api-reference/webhooks/company-document-received) and moves the owner's `document.status` to `received`. When the last one lands, the company moves to `in_progress` and [`company.verified`](/api-reference/webhooks/company-verified) fires. Behind the session is a **document requirement** - see [Requirements](/partner/requirements) for the general model and the other ways to fulfill it. ## Name conflicts If the state rejects the name, the company's `stage` becomes `name_conflict` and a `name_change` requirement opens ([`requirement.created`](/api-reference/webhooks/requirement-created)). Fulfill it with a new name - over the API, or through a hosted link your customer answers on - and Clemta refiles. When Clemta changes a company's legal name for any reason, [`company.name.changed`](/api-reference/webhooks/company-name-changed) tells you. ## What Clemta can and cannot do Clemta fulfills your orders. It does not undo your order. A partner-created company cannot be refunded, archived, or deleted by Clemta - those are your decisions, taken through the API. # How it fits together Source: https://docs.clemta.com/partner/concepts The Partner API object model, the test and live modes, and the one design rule your integration is built on. The Partner API lets you offer company formation and the services around it under your own brand. You create companies for your customers. Clemta forms them, files with the state and the IRS, and delivers the paperwork. You are invoiced once a month at your wholesale prices. Your customer deals only with you. ## The objects ```mermaid theme={null} flowchart LR A[Account
your customer, the incorporator] -->|owns| C[Company] P[Product catalog
your wholesale prices] -.->|ordered as| S[Service order] C --> S C -->|files| TF[Tax filing] C -->|needs| R[Requirement] S -->|needs| R C -->|receives| F[File] C & S & R & F & TF -->|emit| E[Event] --> W[Webhook / GET /events] ``` | Object | What it is | Who moves it | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | | **Account** (`acct_`) | Your customer - the person companies are formed for. Unique per email within your workspace. | You create it, or it is created with a company. | | **Company** (`cmp_`) | One entity Clemta forms, or one that already existed and you bring in (`pre_existing: true`). | You create it. Clemta moves its `status`. | | **Product** | One thing you can offer - formation, EIN, registered agent, bookkeeping - at your wholesale price. A read-only catalog. | Clemta, priced for you. | | **Service order** (`so_`) | One product ordered on one company. Recurring products renew on their own. | You attach. Clemta fulfills, step by step. | | **Tax filing** (`txf_`) | A federal or state return on a company. You buy the right to file, draft it, and submit. | You create and submit. Clemta reviews and files. | | **Requirement** (`rqmt_`) | Something needed from you or your customer: an identity document, a form for a fulfillment step, a new name, extra information. | Opened automatically or by Clemta. Fulfilled by you or, through a link, your customer. | | **File** (`file_`) | A document Clemta publishes on a company: Articles, EIN letter, filed forms. Read-only. | Clemta. | | **Event** (`evt_`) | An immutable record of something that happened, with the resource snapshot embedded. | Clemta. Delivered to your webhooks and listed on [`GET /events`](/api-reference/list-events). | Every resource carries an `object` field naming its type, so a handler can switch on it wherever the resource arrives - nested under `expand[]`, inside an event, or in a webhook. ## Modes and the sandbox Every key is either `clmt_live_` or `clmt_test_`, and everything a key touches inherits its mode. Test and live are separate worlds: a test key never lists, reads, or changes a live object (an id from one never resolves in the other), the same `Idempotency-Key` is a different key in each mode, a test company is never fulfilled, and a test charge never rides a statement. Webhook endpoints are registered per mode, so test events only reach test endpoints. In test mode the whole surface works - companies, orders, requirements, files, and tax filings all exist and every event fires - but nothing advances on its own, because Clemta is not fulfilling it. You advance it: [`POST /sandbox/companies/{id}/simulate`](/api-reference/create-sandbox-simulation) takes an `event` and the fields it needs, and applies the change exactly as a live change would, the once-only rules included, then delivers the resulting events to your test webhooks. ```mermaid theme={null} flowchart LR L[Clemta advances a live company] --> P[(your resources)] S[POST /sandbox/.../simulate
advances a test company] --> P P --> W[your webhooks / GET /events] ``` | `event` | fields | what happens | | ----------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | | [`company.status.changed`](/api-reference/webhooks/company-status-changed) | `status` | status moves. First `active` also fires [`company.incorporated`](/api-reference/webhooks/company-incorporated) | | `company.incorporated` | - | shorthand for `status: active` | | [`company.verified`](/api-reference/webhooks/company-verified) | - | owners' identity settled | | [`company.name.changed`](/api-reference/webhooks/company-name-changed) | `name` | | | [`company.ein.assigned`](/api-reference/webhooks/company-ein-assigned) | `ein` | fires once. A second EIN updates silently | | [`company.entitlements.changed`](/api-reference/webhooks/company-entitlements-changed) | `entitlements` | | | [`service_order.status.changed`](/api-reference/webhooks/service-order-status-changed) | `order`, `step`, `form_required`, `completed` | `form_required` opens a `form` requirement | | [`service_order.completed`](/api-reference/webhooks/service-order-completed) | `order` | fires once | | [`tax_filing.created`](/api-reference/webhooks/tax-filing-created) / [`tax_filing.status.changed`](/api-reference/webhooks/tax-filing-status-changed) | `tax_filing` | | | [`file.created`](/api-reference/webhooks/file-created) | `file_name` | a placeholder PDF is served from the content endpoint | | [`requirement.created`](/api-reference/webhooks/requirement-created) | `message` | an `information` ask from Clemta | | [`invoice.finalized`](/api-reference/webhooks/invoice-finalized) | - | a finalized invoice covering the company's test orders | ## The one design rule Your customer is **yours**. Clemta never emails, texts, or otherwise contacts the people behind a partner-created company. Their identity lives on your account object, and they never become a Clemta user. The pages Clemta hosts for them (identity verification, document signing) carry your brand. Everything that would normally reach the customer reaches *you* instead, as an event - so you can pass it on in your own voice. See [Whitelabel](/partner/whitelabel). ## Where to go next * [Company lifecycle](/partner/company-lifecycle) - statuses, stages, and what fires when. * [Requirements](/partner/requirements) - documents, forms and asks, and how your customer can answer without an API key. * [Service orders](/partner/service-orders) - ordering, fulfillment steps, and the form standard. * [Files](/partner/files) - reading deliverables back. # Partner dashboard Source: https://docs.clemta.com/partner/dashboard What lives at partner.clemta.com: your application, team, keys, webhooks, logs, billing, pricing, branding, and version settings. Everything that is not an API call happens at [partner.clemta.com](https://partner.clemta.com). This page is the map. ## Applying Sign in, create a workspace, and submit the wholesale application: your legal name, website, country, and the programs you want to offer. Keys are issued once the application is approved. A declined application can be revised and resubmitted. ## Team A workspace has one owner and any number of members. | | Owner | Member | | -------------------------------------- | ----- | ------ | | Create test keys | Yes | Yes | | Create, rotate, revoke live keys | Yes | No | | Set a key's IP allowlist | Yes | No | | Register and disable webhook endpoints | Yes | No | | Change version settings and branding | Yes | No | | Accept or decline the price sheet | Yes | No | Invite people from the Team page. Ownership can be transferred to another member. ## API keys Create keys, restrict them to scopes, rotate them with a grace window, revoke them, and set an IP allowlist. Every key shows when it was last used. See [Authentication](/partner/authentication) for what each kind of key can do. ## Webhooks Register an endpoint per mode with its URL, and optionally the event types and an API version to pin its payloads to. The signing secret is shown once, and the public key is readable any time. From here you also roll the secret, disable an endpoint, and browse the last 30 days of deliveries to retry a failed one. See [Webhooks](/partner/webhooks) for the signature and delivery rules. ## Logs Every request to the API and to the dashboard is kept for 30 days with its method, path, status, error code, key, and IP. Search by `request_id` when something needs a second look. The same id is in every error response. ## Billing Your billing account, invoices, monthly statements with their line items, and the usage ledger. Add or replace a payment method here. See [Billing](/partner/billing). ## Pricing Your wholesale price sheet: every product, its cadence, and any negotiated rate. When Clemta changes the sheet, it comes back for your review. Accepting or declining is the owner's call. ## Branding The pages Clemta hosts for your customers, identity upload and document signing, carry only what you set here. A display name and a privacy policy URL are required before any hosted session can be created. Add a support email, a terms URL, a logo and an icon (uploaded through the [Files API](/partner/files) as `business_logo` and `business_icon`), and an accent color. To frame those pages inside your own site, list the origins allowed to do so, up to five. See [Embedding hosted pages](/partner/embedding). ## Settings Two version pins live here. One is the API version your requests resolve to when they send no `Clemta-Version` header. The other is the version webhook payloads are rendered at when an endpoint has no pin of its own. See [Versioning](/partner/versioning). # Embedding hosted pages Source: https://docs.clemta.com/partner/embedding Frame the hosted upload and signing pages inside your own site with the embed SDK, a thin convenience over an iframe. The pages Clemta hosts for your customer (identity upload and document signing) carry your brand and stand on their own by default. When you would rather keep your customer on your own site, you can frame a hosted page inside it. The **embed SDK** is a small, dependency-free helper that renders the frame, sizes it to its content, and hands you the completion signal. It changes nothing about the security model - it is a convenience over an `