CLEATUS REST API and API keys
Create an API key and call the CLEATUS REST API from your own code. Covers plans, authentication, endpoints, pagination, rate limits, errors, and key rotation.
Use the CLEATUS Representational State Transfer (REST) application programming interface (API) to work with CLEATUS from your own code. Your scripts, scheduled jobs, and internal dashboards can read artificial intelligence (AI) recommendations and search contracts. They can also manage your pipeline and tasks, and run workflows. The REST API exposes the same operations as the CLEATUS Model Context Protocol (MCP) Server. It authenticates with an API key instead of an OAuth sign-in. All requests go to one base Uniform Resource Locator (URL).
| Base URL | https://api.cleat.ai/api |
| Auth | API key in the X-Api-Key header |
| Endpoints | 36, under /v1 |
| Format | JavaScript Object Notation (JSON) |
| Plan | DATA + AI + Automations or higher, or API Access |
| Reference | api.cleat.ai/api/docs |
Who can use the REST API
- Plan: The company needs an active subscription or trial on the DATA + AI + Automations plan or higher, or on the API Access plan. See Plans and Pricing.
- Roles: Owners, Admins, and Members can create and revoke keys. Limited Members cannot open the Integrations page.
- Credits: API calls use no credits. Workflows that you run through the API still use credits for their AI steps, as in the web app.
A company on a lower plan gets a 403 error with the api_tier_insufficient marker. A company whose trial has not started gets the same error.
Create an API key
Open Integrations
In CLEATUS, open the company that the key is for. Then open Settings > Integrations.
Open API Keys
In the Data & Automation section, find the API Keys card and click Manage.
Name the key
Click Create new key. Type a name that tells you where the key runs, for example "nightly-pipeline-sync". Names can have up to 120 characters.
Choose a scope
Under Scope, choose Read-only or Read + write. A read-only key can only search and fetch data. A read + write key can also create, update, and delete data. Choose Read-only unless the integration must change data. Then click Create.
Copy the key
The Copy your new API key dialog shows the full key. Click Copy to clipboard and store the key in your secrets manager. Then click I've saved it.
CLEATUS shows each key only once:
CLEATUS stores only a hash of the key, so it cannot show the key again. If you lose a key, revoke it and create a new key.
Every key starts with ck_live_. The Your API Keys list shows each active key with its name, scope, and key prefix. It also shows the creation date, the expiry date, and the time of the last use.
Revoke a key
- On the API Keys page, click Revoke next to the key.
- Click Revoke key to confirm.
The key stops working on the next request, and the integration gets 401 errors. You cannot undo a revocation. Revoked and expired keys move to the Inactive keys list, which CLEATUS keeps for audit.
Authenticate
Send the key in the X-Api-Key header on every request. Every endpoint path starts at the base URL https://api.cleat.ai/api.
curl https://api.cleat.ai/api/v1/profile \
-H "X-Api-Key: $CLEATUS_API_KEY"
This call returns the company that the key acts for and the user who created the key. Use it to test a new key.
- The REST API accepts only the
X-Api-Keyheader. It rejects OAuth Bearer tokens with a 401 error. Bearer tokens work only on the MCP Server. - Never put the key in a URL or a query string.
- Each key acts for one company and for the user who created it. User-specific endpoints use that user. Examples are notifications,
current_userin the profile, and tasks assigned tome.
CLEATUS GovCloud:
This article covers the commercial CLEATUS service at api.cleat.ai. CLEATUS GovCloud uses a different API address.
If your company uses GovCloud, contact support@cleat.ai for the correct address.
Endpoints
GET endpoints read data, so any key can call them. POST, PATCH, and DELETE endpoints change data, so they need a Read + write key. The groups match the sections of the reference.
| Group | Endpoints |
|---|---|
| Opportunities | GET /v1/recommendations (your AI-ranked Recommended feed), POST /v1/recommendations/dismiss, POST /v1/recommendations/undismiss, GET /v1/opportunities/search (opportunities scored for your company), GET /v1/opportunities/{opportunity_id} (detail and documents) |
| Contracts | GET /v1/contracts/search (keyword and meaning-based search across federal, state, and local contracts; add scope=all to include closed and awarded contracts) |
| Market Intelligence | GET /v1/market/search (past awards, agencies, contractors, government people, and North American Industry Classification System (NAICS) codes) |
| Pipeline | POST /v1/pipeline/add, GET /v1/pipeline/search, GET /v1/pursuits/{pursuit_id}, PATCH /v1/pursuits/{pursuit_id} |
| Tasks | GET /v1/tasks, POST /v1/tasks, PATCH /v1/tasks/{task_id}, DELETE /v1/tasks/{task_id} |
| Saved Searches | GET /v1/saved-searches, POST /v1/saved-searches, PATCH /v1/saved-searches/{saved_search_id}, DELETE /v1/saved-searches/{saved_search_id} |
| Documents | GET /v1/documents, GET /v1/documents/search, POST /v1/documents/folders, DELETE /v1/documents/{item_id} (Document Hub files and folders) |
| Workflows | GET /v1/workflows, POST /v1/workflows, POST /v1/workflows/{workflow_id}/activate, POST /v1/workflows/{workflow_id}/run, GET /v1/workflows/runs/{run_id}, DELETE /v1/workflows/{workflow_id}, GET /v1/workflow-templates |
| Teams | GET /v1/teams (teams and their members) |
| Context | GET /v1/profile (Capture Profile and current user), GET /v1/notifications, POST /v1/notifications/read, GET /v1/credits |
| Security | GET /v1/security/settings (exports the company's members, API keys, integrations, and webhooks; the key's creator must be an Owner or Admin) |
The opportunity detail endpoint also returns the AI summary and the parsed Federal Acquisition Regulation (FAR) sections. A new workflow is always a draft. You can run a draft only with dry_run: true. Activate the workflow before you run it live.
Request format
GETandDELETErequests take parameters in the path and the query string. Send a list as comma-separated values, for examplestates=VA,MD.- Send dates as
YYYY-MM-DDor as a full International Organization for Standardization (ISO) 8601 timestamp. POSTandPATCHrequests take a JSON body. Set the headerContent-Type: application/jsonwith nocharsetparameter.- Successful responses return JSON.
Example: get your top recommendation
This request gets the highest-scoring opportunity from your Recommended feed:
curl "https://api.cleat.ai/api/v1/recommendations?limit=1&min_score=80" \
-H "X-Api-Key: $CLEATUS_API_KEY"
Sample response:
{
"results": [
{
"id": "0f3c9a7e1b2d4c5f8a6e9d0b1c2a3f4e",
"title": "Enterprise IT Service Desk Support",
"agency": "Department of Veterans Affairs",
"match_score": 91,
"naics": "541512",
"set_aside": "SBA",
"posted_date": "2026-10-02T00:00:00.000Z",
"deadline_date": "2026-11-04T00:00:00.000Z",
"notice_type": "Solicitation",
"solicitation_number": "36C10B26Q0001",
"estimated_value_low": null,
"estimated_value_high": null,
"period_of_performance": null,
"recommendation_reason": "Matches your service desk and cloud support capabilities.",
"view_url": "https://www.cleat.ai/dashboard/acme/acme-federal/contracts/0f3c9a7e1b2d4c5f8a6e9d0b1c2a3f4e",
"in_pipeline": false,
"pursuit_view_url": null
}
],
"cursor": "eyJvIjoxLCJsIjoxfQ",
"has_more": true,
"total_count": 37
}
match_scoreis the 0 to 100 score that the Recommended page shows. The defaultmin_scoreis 80, the same as that page.recommendation_reasonis the AI explanation for the match.view_urlopens the opportunity in CLEATUS.- By default, the feed leaves out opportunities that are already in your pipeline. It also leaves out opportunities whose deadline has passed. Set
exclude_pipeline=falseorinclude_expired=trueto include them.
Pagination
List endpoints return the same envelope: results, cursor, has_more, and total_count.
- Set
limitto the page size that you want. Each endpoint sets its own maximum, for example 50 for searches and 100 for recommendations. - If
has_moreistrue, send the same request again withcursorset to the value from the last response. - Stop when
has_moreisfalse. Thecursoris thennull.
Treat the cursor as an opaque string. Some list endpoints also accept count_only=true, which returns the count without the rows. GET /v1/market/search has no cursor: it returns up to limit results for each result type.
Rate limits and quotas
Rate limits: Each key gets 100 reads and 30 writes per minute. A request over the limit gets a 429 error. The error message gives the number of seconds to wait, for example "Retry after 42s". The response has no Retry-After header.
Contract search quotas: GET /v1/contracts/search has extra quotas for each company. Every key and every MCP connector for the company share these quotas.
| Quota | Limit | Resets |
|---|---|---|
| Searches per day | 2,500 | At midnight Coordinated Universal Time (UTC) |
| Distinct records per billing cycle | 30,000 | When your billing cycle renews |
| Distinct state and local records per billing cycle | 15,000 | When your billing cycle renews |
Reading the same record again does not count against the record quotas. Every contract search response has a quota block with the used and limit values for each quota. Watch it, so that you do not reach a limit. When a quota runs out, the endpoint returns a 429 error that names the quota. Do not retry in a loop.
Errors
API errors return a JSON body with a message and a code:
{
"message": "REST API accepts X-Api-Key only. OAuth Bearer tokens should use the MCP endpoint.",
"code": "UNAUTHORIZED"
}
Some messages start with a stable marker, for example api_scope_insufficient:. Branch on the marker, not on the full message text. For an invalid parameter, the message is "Input validation failed", and an issues array names each invalid field.
| Status | code | Cause | What to do |
|---|---|---|---|
| 400 | BAD_REQUEST | A parameter or a body field is missing or invalid. | Fix the fields that the issues array names. |
| 401 | UNAUTHORIZED | The X-Api-Key header is missing, the key is wrong or revoked, or you sent a Bearer token. The api_key_expired marker means that the key passed its expiry date. | Check the header. If the key expired, create a new key. |
| 403 | FORBIDDEN | api_scope_insufficient: a read-only key called a write endpoint. api_tier_insufficient: the plan does not include the API, or the trial has not started. subscription_inactive: the subscription is inactive, or the key's creator no longer has access to the company. | Use a Read + write key, upgrade the plan, or create a key from an active user. |
| 404 | NOT_FOUND | The path or the record does not exist. A path without the /api prefix gets an HTML 404 page instead of JSON. | Check the ID and the path. |
| 429 | TOO_MANY_REQUESTS | The key passed its rate limit, or the company used up a contract search quota. | Wait for the time in the message, or wait for the quota to reset. |
| 500 | INTERNAL_SERVER_ERROR | An error occurred on the CLEATUS side. | Retry once after a short wait. If the error continues, contact support. |
Key expiry and rotation
Every new key expires one year after you create it. The API Keys page shows the expiry date of each key. After that date, the API rejects the key with a 401 error and the api_key_expired marker. The key then moves to Inactive keys.
You cannot extend a key. To rotate a key:
- Create a new key with the same scope.
- Put the new key in your integration's secrets.
- Call
GET /v1/profilewith the new key to test it. - Revoke the old key.
Rotate each key before its expiry date. Also rotate a key when its creator leaves the company, or when the key may have leaked. Some older keys show never expires. They date from before key expiry existed, and they have read + write access. Replace them with a new key that has the scope that you need.
Security
- Store keys as secrets. Keep each key in a secrets manager or an environment variable. Never commit a key to source control.
- Call the API from a server. Do not put a key in browser or mobile app code. Anyone who loads that code can read the key.
- Scope each key to one company. A key reads and changes data only in the company that you created it in. To work with more than one company, create a key in each company.
- Use one key for each integration. You can then revoke one key without stopping your other integrations.
- Grant the least access. Use Read-only unless the integration must create, update, or delete data.
- Create keys from a lasting account. A key acts for the user who created it. When that user leaves the company, the key stops working.
- Watch for unexpected use. The API Keys page shows when each key was last used. CLEATUS logs the endpoint, the key, the result status, and the response time for each request. For searches, it also logs the search text and the result count.
- Revoke a leaked key at once. Then create a new key and update your integration.
Full reference
The interactive reference at api.cleat.ai/api/docs lists every endpoint with its parameters and request bodies. The View API Docs button on the API Keys page opens it. The machine-readable OpenAPI specification is at api.cleat.ai/api/openapi.json.
Known gaps in the reference:
The reference text says that the API uses OAuth Bearer tokens. That is not correct: the REST API accepts only the
X-Api-Key header. Try it out sends requests without the /api prefix and without your key, so those requests
fail. The reference does not describe response bodies. Test with curl or your own client. The Zapier endpoints in
the reference are for the Zapier integration and do not accept API keys.
REST API or MCP Server
Both surfaces run the same operations against your live CLEATUS data. Choose by who makes the call.
| REST API | MCP Server | |
|---|---|---|
| Who calls | Your code | An AI assistant, such as Claude, ChatGPT, or Cursor |
| Credential | API key in the X-Api-Key header | OAuth 2.1 sign-in, then a Bearer token |
| Lifetime | One year, or until you revoke the key | Access tokens last one hour; refresh tokens, 30 days |
| Access | Read-only or Read + write | Full access to the company that you pick |
| Plan | DATA + AI + Automations or higher, or API Access | DATA + AI or higher |
| Operations | 36 endpoints, including the security export | 36 tools, including a documentation tool |
| Rate limits | 100 reads and 30 writes per minute for each key | 100 reads and 30 writes per minute for each access token |
| Use it for | Scheduled jobs, data syncs, and dashboards | Questions and tasks in a conversation |
For no-code automation, use Zapier. To make CLEATUS send data to your own endpoint when an event happens, use webhooks.
Support
- Email: support@cleat.ai. Include the endpoint, the response status, and the time of a failing request. Never send the full key.
- Security disclosures: security@cleat.ai
- Security and compliance: https://www.cleat.ai/security
