> ## 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 `