Servers
4 operations under /v1/servers (GET POST): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript.
Base URL: https://api.codespar.dev
Every operation below requires a Bearer token. See Authentication.
The Servers API lets you browse CodeSpar's catalog of MCP servers. Each server represents an integration with a commerce provider -- a payment gateway, shipping carrier, fiscal authority, messaging platform, banking API, ERP system, or crypto exchange.
Use the Servers API to understand what integrations are available, discover capabilities before creating sessions, and build dynamic UIs that show users which providers they can connect.
Base URL: https://api.codespar.dev
All endpoints require authentication via Bearer token. See Authentication.
GET /v1/servers
Returns the server catalog with filtering and search capabilities. Results are paginated.
Auth required: Yes (scope: servers:read)
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
category | string | -- | Filter by category: payments, fiscal, logistics, messaging, banking, erp, crypto |
country | string | -- | Filter by country code (ISO 3166-1 alpha-2): BR, MX, AR, CO, CL |
q | string | -- | Full-text search across server name, description, and capabilities |
status | string | -- | Filter by status: stable, beta, alpha, deprecated |
auth_type | string | -- | Filter by auth type: api_key, path_secret, oauth, cert, hmac_signed, none |
limit | number | 50 | Results per page (max 100) |
offset | number | 0 | Pagination offset |
Response schema
{
"data": [
{
"id": "string",
"name": "string",
"description": "string",
"category": "string",
"countries": ["string"],
"capabilities": ["string"],
"auth_type": "string",
"status": "string",
"tools_count": "number",
"icon_url": "string"
}
],
"total": "number",
"limit": "number",
"offset": "number"
}Example: list all servers
curl "https://api.codespar.dev/v1/servers" \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK:
{
"data": [
{
"id": "stripe",
"name": "Stripe",
"description": "Global payment processing platform. Supports cards, Pix, boleto, and 135+ currencies.",
"category": "payments",
"countries": ["BR", "MX", "AR", "CO", "CL"],
"capabilities": ["checkout", "subscriptions", "refunds", "pix", "boleto", "cards"],
"auth_type": "api_key",
"status": "stable",
"tools_count": 12,
"icon_url": "https://codespar.dev/icons/stripe.svg"
},
{
"id": "mercado-pago",
"name": "Mercado Pago",
"description": "Latin America's leading payment platform. Native Pix, boleto, and Mercado Credito.",
"category": "payments",
"countries": ["BR", "MX", "AR", "CO", "CL"],
"capabilities": ["pix", "boleto", "checkout", "wallet", "installments"],
"auth_type": "oauth",
"status": "stable",
"tools_count": 15,
"icon_url": "https://codespar.dev/icons/mercado-pago.svg"
}
],
"total": 114,
"limit": 50,
"offset": 0
}Example: filter by category
Retrieve only payment servers:
curl "https://api.codespar.dev/v1/servers?category=payments" \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK:
{
"data": [
{
"id": "stripe",
"name": "Stripe",
"description": "Global payment processing platform. Supports cards, Pix, boleto, and 135+ currencies.",
"category": "payments",
"countries": ["BR", "MX", "AR", "CO", "CL"],
"capabilities": ["checkout", "subscriptions", "refunds", "pix", "boleto", "cards"],
"auth_type": "api_key",
"status": "stable",
"tools_count": 12,
"icon_url": "https://codespar.dev/icons/stripe.svg"
},
{
"id": "asaas",
"name": "Asaas",
"description": "Brazilian payment platform specializing in Pix, boleto, and recurring billing.",
"category": "payments",
"countries": ["BR"],
"capabilities": ["pix", "boleto", "subscriptions", "split_payments"],
"auth_type": "api_key",
"status": "stable",
"tools_count": 10,
"icon_url": "https://codespar.dev/icons/asaas.svg"
}
],
"total": 12,
"limit": 50,
"offset": 0
}Example: filter by country
Retrieve servers available in Mexico:
curl "https://api.codespar.dev/v1/servers?country=MX" \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK:
{
"data": [
{
"id": "stripe",
"name": "Stripe",
"description": "Global payment processing platform. Supports cards, Pix, boleto, and 135+ currencies.",
"category": "payments",
"countries": ["BR", "MX", "AR", "CO", "CL"],
"capabilities": ["checkout", "subscriptions", "refunds", "pix", "boleto", "cards"],
"auth_type": "api_key",
"status": "stable",
"tools_count": 12,
"icon_url": "https://codespar.dev/icons/stripe.svg"
},
{
"id": "conekta",
"name": "Conekta",
"description": "Mexican payment platform. Native SPEI, OXXO cash payments, and card processing.",
"category": "payments",
"countries": ["MX"],
"capabilities": ["spei", "oxxo", "cards", "checkout"],
"auth_type": "api_key",
"status": "stable",
"tools_count": 8,
"icon_url": "https://codespar.dev/icons/conekta.svg"
},
{
"id": "cfdi",
"name": "CFDI",
"description": "Mexican fiscal document generation (Comprobante Fiscal Digital por Internet) via SAT.",
"category": "fiscal",
"countries": ["MX"],
"capabilities": ["cfdi_ingreso", "cfdi_egreso", "cfdi_traslado", "cancelation"],
"auth_type": "cert",
"status": "stable",
"tools_count": 6,
"icon_url": "https://codespar.dev/icons/cfdi.svg"
}
],
"total": 18,
"limit": 50,
"offset": 0
}Example: full-text search
Search for servers that support Pix:
curl "https://api.codespar.dev/v1/servers?q=pix" \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK:
{
"data": [
{
"id": "stripe",
"name": "Stripe",
"description": "Global payment processing platform. Supports cards, Pix, boleto, and 135+ currencies.",
"category": "payments",
"countries": ["BR", "MX", "AR", "CO", "CL"],
"capabilities": ["checkout", "subscriptions", "refunds", "pix", "boleto", "cards"],
"auth_type": "api_key",
"status": "stable",
"tools_count": 12,
"icon_url": "https://codespar.dev/icons/stripe.svg"
},
{
"id": "mercado-pago",
"name": "Mercado Pago",
"description": "Latin America's leading payment platform. Native Pix, boleto, and Mercado Credito.",
"category": "payments",
"countries": ["BR", "MX", "AR", "CO", "CL"],
"capabilities": ["pix", "boleto", "checkout", "wallet", "installments"],
"auth_type": "oauth",
"status": "stable",
"tools_count": 15,
"icon_url": "https://codespar.dev/icons/mercado-pago.svg"
},
{
"id": "asaas",
"name": "Asaas",
"description": "Brazilian payment platform specializing in Pix, boleto, and recurring billing.",
"category": "payments",
"countries": ["BR"],
"capabilities": ["pix", "boleto", "subscriptions", "split_payments"],
"auth_type": "api_key",
"status": "stable",
"tools_count": 10,
"icon_url": "https://codespar.dev/icons/asaas.svg"
}
],
"total": 5,
"limit": 50,
"offset": 0
}Example: combine filters
Retrieve stable payment servers in Brazil:
curl "https://api.codespar.dev/v1/servers?category=payments&country=BR&status=stable" \
-H "Authorization: Bearer csk_live_abc123..."GET /v1/servers/:id/tools
Returns a server's tool list with input schemas. (There is no standalone GET /v1/servers/:id: server metadata comes from the list endpoint's rows; this endpoint serves the tools; GET /v1/servers/:id/auth-schema serves the credential shape the connect flow needs.)
Auth required: Yes (scope: servers:read)
curl example
curl https://api.codespar.dev/v1/servers/stripe/tools \
-H "Authorization: Bearer csk_live_abc123..."Response -- 200 OK
{
"tools": [
{
"name": "stripe_create_checkout_session",
"description": "Create a Stripe Checkout session with a payment link",
"input_schema": {
"type": "object",
"properties": {
"line_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"price_data": {
"type": "object",
"properties": {
"currency": { "type": "string" },
"product_data": {
"type": "object",
"properties": {
"name": { "type": "string" }
}
},
"unit_amount": { "type": "number" }
}
},
"quantity": { "type": "number" }
}
}
},
"mode": {
"type": "string",
"enum": ["payment", "subscription", "setup"]
},
"success_url": { "type": "string" },
"cancel_url": { "type": "string" }
},
"required": ["line_items", "mode"]
}
},
{
"name": "stripe_create_refund",
"description": "Refund a Stripe payment",
"input_schema": {
"type": "object",
"properties": {
"payment_intent": { "type": "string", "description": "ID of the PaymentIntent to refund" },
"amount": { "type": "number", "description": "Amount to refund in cents (partial refund). Omit for full refund." },
"reason": { "type": "string", "enum": ["duplicate", "fraudulent", "requested_by_customer"] }
},
"required": ["payment_intent"]
}
}
]
}Server-specific tools (like stripe_create_checkout_session) are only available in sessions that connect to that server. The 14 meta-tools are always available regardless of which servers are connected.
Server categories
| Category | Examples |
|---|---|
payments | Stripe, Mercado Pago, Asaas, PagSeguro, Pagarme, Conekta, Inter, Sicredi |
fiscal | NF-e, NFS-e, SPED, CT-e, MDFe, CFDI |
logistics | Correios, Jadlog, Loggi, Mercado Envios, Total Express, DHL, Estafeta |
messaging | Twilio, WhatsApp Business, SendGrid, Mailgun, Amazon SNS |
banking | Inter, Itau, Bradesco, Banco do Brasil, Sicoob, Nubank |
erp | Bling, Tiny, Omie, TOTVS, ContaAzul, Nuvemshop |
crypto | Mercado Bitcoin, Foxbit, Binance Pay, Coinbase Commerce |
Per-category counts change as the catalog grows; query GET /v1/servers?category=<name> for live numbers.
Server status values
| Status | Description | Recommendation |
|---|---|---|
stable | Production-ready, fully tested, SLA-backed | Safe for production use |
beta | Functional but may have breaking changes in minor versions | Safe for staging; pin the server version in production |
alpha | Experimental, limited support, may be removed | Development and testing only |
deprecated | Scheduled for removal; an alternative is available | Migrate to the suggested replacement |
Authentication types
Each server requires one of these authentication methods, configured in the Auth Configs section of the dashboard:
| Auth type | Description | Examples |
|---|---|---|
api_key | Authenticate with a secret key from the provider | Stripe, Asaas, SendGrid |
path_secret | Secrets embedded in URL path plus optional companion header | Z-API, Take Blip, Evolution API |
oauth | OAuth 2.0 flow for user-level access | Mercado Pago, Melhor Envio |
cert | mTLS with X.509 client certificate (PEM) | Banco do Brasil, Itaú, Bradesco, Santander, Caixa, Sicoob, Sicredi, C6, Original |
hmac_signed | Per-request HMAC signature over timestamp + method + path + body | Foxbit |
jwt_ecdsa | Per-request ES256 JWT signed with an ECDSA P-256 private key | Coinbase Developer Platform |
two_header | Two co-equal credential headers, no Authorization Bearer | Cielo, Transbank, Kushki, Payway |
none | No credentials required | Brasil API |
Rate limits
The catalog reads on this page (GET /v1/servers, /v1/servers/:id/tools,
/v1/servers/:id/auth-schema) carry no rate limit of their own. The limiter
that exists applies to tool execution, and it is not tiered by plan.
It is a token bucket keyed by (account, server) — so the budget is per
upstream provider, not per API key and not per plan. The default bucket is a
capacity of 60 with 1 token/second of refill; a few providers that publish
generous ceilings get more (Stripe 300 / 25 per second, Asaas 120 / 10 per
second). Buckets are held in the API process, so a multi-replica deployment
gives each replica its own.
Exceeding it answers 429 with a Retry-After header in seconds and
retry_after_ms in the body:
{
"error": "rate_limited",
"server": "asaas",
"retry_after_ms": 1400,
"message": "Rate limit reached for server \"asaas\". Retry in ~2s."
}There are no X-RateLimit-Limit / -Remaining / -Reset headers. Read
Retry-After and back off with jitter.
Rate limits are not billing — see Billing for the pricing model.
Error responses
| Status | Error code | Description |
|---|---|---|
400 | invalid_query | Invalid query parameter value |
401 | unauthorized | Invalid or missing API key |
403 | forbidden | The key does not hold the servers:read scope |
404 | not_found | Server ID does not exist in the catalog |
429 rate_limited does not appear on these three endpoints — it belongs to tool
execution, on POST /v1/sessions/:id/tool-calls.
Next steps
Every operation, from the spec
Generated from the published OpenAPI document, so it never drifts from what the API actually serves. The section above is written by hand and carries what a schema cannot: the object model, field rules, and the order to call things in.
GET /v1/servers
https://api.codespar.dev/v1/serversList the MCP servers this project can attach to a session
DEPRECATED alias of GET /v1/providers (ent#979), kept for two releases. Same handler, same required scope; switch the path and nothing else changes.
The catalog POST /v1/sessions draws its servers ids from. total is everything visible to this project, filtered is what survived the query parameters, and servers is the filtered page; the route does not paginate, so filtered and servers.length agree.
Visibility is per project: another project's generated (gen_-prefixed) servers are absent, global catalog rows always present. Presence here is NOT permission to invoke — that is gated separately on a connected account, which is what POST /v1/connect/start establishes.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
category | string | no | — |
country | string | no | — |
q | string | no | — |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | Bad Request — the body or query did not match the schema. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
filtered | integer | yes | — |
servers | array of ServerCatalogRow | yes | — |
total | integer | yes | — |
curl -X GET https://api.codespar.dev/v1/servers \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/servers HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.get(
"https://api.codespar.dev/v1/servers",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/servers", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const result = await cs.api.get("/v1/servers");{
"total": 0,
"filtered": 0,
"servers": [
{
"id": "servercatalogrow_0000000000000000",
"name": "Example",
"pkg": "string",
"category": "string",
"country": "string",
"auth_type": "string",
"tools_count": 1,
"description": "string",
"status": "string",
"provider_homepage": "string",
"provider_logo_url": "https://example.com/hook",
"provider_logo_fallback_url": "https://example.com/hook",
"provider_docs_url": "https://example.com/hook",
"sandbox_available": true,
"sandbox_url": "https://example.com/hook",
"description_pt_br": "string",
"subaccount_provisionable": true,
"engine_provisionable": true,
"engine_status": "none",
"connect_fields": 0,
"connectable": true
}
]
}GET /v1/servers/{id}/auth-schema
https://api.codespar.dev/v1/servers/{id}/auth-schemaRead the credential form a provider needs, without reading any credential
What to ask an operator for before connecting this provider, and where the request will go once connected. It NEVER returns a stored secret: the vault is write-only from this side, and fields describes inputs to collect, not values that exist.
AN EMPTY fields DOES NOT MEAN NOTHING TO DO. oauth collects nothing here because the browser leg starts at POST /v1/connections/start instead, and none needs no credential. Every other type returns one field per catalog-declared ref, which is exactly the key set POST /v1/connections validates the secret object against: jwt_ecdsa asks for the CDP API key name and its private key, cdp for the CDP API key id, API key secret and wallet secret. Both CDP forms are served only where the deployment enables CDP self-serve connect (CDP_SELF_SERVE_CONNECT, off by default); otherwise they come back empty. A form type whose catalog row declares no refs comes back empty and cannot be connected; connectable on GET /v1/servers already says so per row.
base_url IS ENVIRONMENT-RESOLVED against the credential in hand: a test key sees the provider's test host when the catalog declares one, and the live host otherwise. It is the empty string when the provider has no endpoint row, which is a catalog gap rather than a value to dial.
This is the path that shipped first; GET /v1/providers/{slug}/auth-schema is the same handler at the canonical path (ent#979) and is not yet described in this document, so the full response is described HERE and nothing is withheld until you switch paths.
The visibility gate in front of this operation only hides GENERATED providers (ids prefixed gen_) that belong to another project. Any id without that prefix passes the gate, including an id that names no provider at all. Past the gate, a provider that is genuinely absent from the catalog is a 404 as well, so this operation does distinguish a real provider from an invented one.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The provider id, which is also the catalog row's primary key. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | The provider is not visible to this project. Not the apiError envelope and not { error: "not_found" }: a third shape, built at the route. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
auth_type | string | yes | LEFT OPEN ON PURPOSE, and the reason is measured rather than cautious. The column admits nine values today — api_key, path_secret, oauth, cert, none, hmac_signed, jwt_ecdsa, two_header, cdp — under a CHECK constraint that has been widened four times (migrations 0064, 0066, 0074, 0091, over the six of 0026). The handler casts the column straight into this field, so the set of values a client can receive is the DB's, not any narrower published enum. Closing this to six would describe a wire that already carries more. |
base_url | string | yes | The host a call to this provider will be sent to, in the caller's environment. Empty string when the provider has no endpoint row. |
environment | "live" | "test" | yes | Taken from the calling credential, and what base_url was resolved against. |
fields | array of object | yes | In the order the form should render, which is the catalog's declared order: the visible field before the masked one for the multi-field types. |
oauth_authorize_url | string,null | yes | Where the browser leg starts, environment-resolved the same way. Null for every auth type other than oauth, and also null for an oauth provider with no configuration row. |
server_id | string | yes | — |
curl -X GET https://api.codespar.dev/v1/servers/{id}/auth-schema \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/servers/{id}/auth-schema HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.get(
"https://api.codespar.dev/v1/servers/{id}/auth-schema",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/servers/{id}/auth-schema", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const result = await cs.api.get("/v1/servers/{id}/auth-schema", {
path: {
id: "srv_0000000000000000"
}
});{
"server_id": "srv_0000000000000000",
"auth_type": "string",
"environment": "live",
"base_url": "https://example.com/hook",
"oauth_authorize_url": "https://example.com/hook",
"fields": [
{
"name": "Example",
"kind": "api_key",
"label": "Example",
"header_name": "Example"
}
]
}GET /v1/servers/{id}/tools
https://api.codespar.dev/v1/servers/{id}/toolsList the tools a provider exposes
Every tool registered for this provider, ordered by name, with no limit and no cursor: total is the length of tools and the two cannot disagree.
AN UNKNOWN PROVIDER IS 200 HERE, NOT 404, and it is the one thing worth knowing about this operation. The visibility gate in front of this operation only hides GENERATED providers (ids prefixed gen_) that belong to another project. Any id without that prefix passes the gate, including an id that names no provider at all. There is no second check after it, so an id that names nothing reaches the tool query, matches no rows, and comes back as a well-formed empty list with that id echoed in server_id. An empty tools therefore means either a real provider with nothing registered or a provider that does not exist, and this response cannot tell you which. The 404 below is reachable only for another project's generated provider.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The provider id. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
404 | object | The provider is not visible to this project. Not the apiError envelope and not { error: "not_found" }: a third shape, built at the route. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
server_id | string | yes | Echoes the id from the path, whether or not it named anything. |
tools | array of object | yes | — |
total | integer | yes | Always equal to the length of tools. |
curl -X GET https://api.codespar.dev/v1/servers/{id}/tools \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/servers/{id}/tools HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.get(
"https://api.codespar.dev/v1/servers/{id}/tools",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/servers/{id}/tools", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const result = await cs.api.get("/v1/servers/{id}/tools", {
path: {
id: "srv_0000000000000000"
}
});{
"server_id": "srv_0000000000000000",
"total": 0,
"tools": [
{
"name": "Example",
"description": "string"
}
]
}POST /v1/servers/{id}/verify-connection
https://api.codespar.dev/v1/servers/{id}/verify-connectionAsk the provider whether this project's stored credential still works
Issues ONE safe read against the provider using the credential this project has stored for it, and reports what came back. POST because it leaves the process and spends a provider call, not because it changes anything here: no state of yours is altered by it. It takes NO REQUEST BODY, and anything sent is ignored.
WHICH READ depends on the provider. A handful ship a bespoke recipe, and those are the ones that can return an account summary. Everything else re-runs the provider's declared functional probe, the same authenticated read used to confirm a sandbox works when it is first set up; that path returns no account. A provider with neither answers 501.
READ THE STATUS, NOT THE BODY, TO DECIDE WHAT TO DO. Seven failure codes map onto seven distinct statuses, and only ONE of them is worth retrying unchanged (502). 401 is a verdict on the credential; 424 means there is no connection to test yet; 409 means the host redirected and never judged the credential, so a retry gets the same non-answer; 501 and 503 are configuration, not weather.
THE 502 IS WIDER THAN ITS NAME. provider_unreachable is what every non-2xx that is not a redirect and not a 401 or 403 becomes, so a provider answering 400, 404, 409, 422 or 429 arrives here as 502 with the provider's own status in status. An agent that retries every 502 will retry a 429 sensibly and a 400 forever. Read status before deciding.
TWO DIFFERENT BODIES SHARE THE 404, from two different lines: the visibility gate's { error, server_id }, and the verify outcome's { ok: false, provider, error } when the credential resolver finds no such provider in the catalog. Both are described below.
This is the path that shipped first; POST /v1/providers/{slug}/verify-connection is the same handler at the canonical path (ent#979) and is not yet described in this document.
The visibility gate in front of this operation only hides GENERATED providers (ids prefixed gen_) that belong to another project. Any id without that prefix passes the gate, including an id that names no provider at all.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | The provider id. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
401 | object | provider_rejected. The provider answered 401 or 403: it looked at the credential and said no. Retrying unchanged will fail the same way. |
403 | object | shared_sandbox_operation_refused or shared_sandbox_credential_not_test. The project's connection is the platform's shared sandbox account. Test connection on it runs only the operation its provider lists for verify, with no account in the answer; a provider with none, or whose shared credential is not shown to be a test one, is refused before anything is sent. Not a verdict on a credential of yours: connect your own account for this provider. |
404 | object | object | Two shapes under one status. The route's own gate answers { error, server_id } before any work happens; the credential resolver answers the verify outcome's server_unknown when the provider is absent from the catalog. Parse the union. |
409 | object | redirect_not_followed. The configured host answered 3xx. The probe is issued with redirects disabled on purpose, so the credential was never judged by anyone: this is the absence of a verdict, not a negative one. Retrying cannot change it; the host or the catalog entry has to. |
422 | object | test_venue_unavailable. The project is in environment="test" and this provider cannot be exercised there: its catalog entry classifies test_venue as none (the provider runs no test environment, so a call would land on production with a real effect) or unclassified (nobody has established what it does in test). Not a verdict on the credential and not retryable — the identical request from a live project reaches the provider (ent#722). |
424 | object | not_connected. There is nothing to verify: either no active connection exists for this project and provider, or one exists and its stored credential did not resolve to a value. Connect the provider, or reconnect it. |
501 | object | verify_unsupported. This provider ships neither a bespoke recipe nor a declared probe, so there is no safe read to issue. Nothing is wrong with the credential and nothing about it has been learned; the first real call is where authentication errors will surface. |
502 | object | provider_unreachable. EVERY non-2xx that is not a redirect and not a 401 or 403 lands here, together with network failures and the per-call timeout (10 seconds by default, deployment-configurable). That includes a provider's 400, 404, 409, 422 and 429. Only some of those are worth retrying, and status is the field that separates them. |
503 | object | endpoint_missing. The provider is in the catalog but the row that says where to reach it is missing or contradicts how the connection was stored. A catalog or connection problem on our side, not a verdict on the credential and not a provider outage. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
account | object | no | ABSENT on the probe path, and absent on the recipe path whenever the recipe found nothing it recognised in the response. Present means the read reached a real account; absent does NOT mean it did not. |
latency_ms | integer | yes | Wall-clock milliseconds around the outbound call. |
ok | true | yes | — |
provider | string | yes | The provider id from the path. |
curl -X POST https://api.codespar.dev/v1/servers/{id}/verify-connection \
-H "Authorization: Bearer $CODESPAR_API_KEY"POST /v1/servers/{id}/verify-connection HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.post(
"https://api.codespar.dev/v1/servers/{id}/verify-connection",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/servers/{id}/verify-connection", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const r = await cs.api.response("post", "/v1/servers/{id}/verify-connection", {
path: {
id: "srv_0000000000000000"
}
});
// r.status is one of the documented statuses (200, 403, 422),
// each with its own body shape in r.data; nothing here throws on 403.
if (r.ok) {
console.log(r.data);
}{
"ok": true,
"provider": "string",
"account": {
"id": "obj_0000000000000000",
"name": "Example",
"extras": {}
},
"latency_ms": 0
}MCP Servers
8 operations under /v1/mcp-servers (GET POST PATCH DELETE): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript.
Providers
4 operations under /v1/providers (GET POST): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript.