Skip to main content
API reference

Connections

Generated HTTP reference for the 10 operations the published OpenAPI document describes under connections.

12 min read
View MarkdownEdit on GitHub

Connections

This page is generated from the published OpenAPI document. It is complete with respect to that document and says nothing about surfaces the document does not describe yet. See what is generated here for what that means.

Base URL: https://api.codespar.dev

Every operation below requires a Bearer token. See Authentication.

A connection stores a provider credential (encrypted in the vault) plus its merchant config, scoped to your account and project. Connections are org-scoped resources under /v1/connections; sessions read them, they don't own them. The one session-scoped surface is the read-only list of what a given session can currently reach.

Base URL: https://api.codespar.dev

All endpoints require authentication via Bearer token. See Authentication.


POST /v1/connections

Creates a connection (or rotates the credential of an existing one for the same server_id/user_id). The secret is encrypted into the vault; it is never returned by any read endpoint.

Request body

FieldTypeRequiredDescription
server_idstringYesProvider identifier from the servers catalog
secretstring | objectYesThe credential. A string for single-secret providers; an object of named secrets for path-secret providers (each key must match the provider's declared secret names; extra or missing keys are rejected)
display_namestringNoOperator-facing label, max 128 chars
user_idstringNoEnd-user binding for per-user connections
connection_metadataobjectNoProvider-specific merchant config the agent shouldn't have to know (fiscal company id, split wallet id, default customer id). Max 64 keys / 32 KB serialized. Merged into upstream calls at execute time

Response -- 201 Created (or 200 OK on rotation)

{
  "id": "conn_abc123",
  "user_id": null,
  "server_id": "asaas",
  "auth_type": "api_key",
  "status": "connected",
  "display_name": "Asaas production",
  "metadata": {},
  "connection_metadata": { "default_customer_id": "cus_000042" },
  "cert_metadata": {},
  "created_at": "2026-07-01T12:00:00Z",
  "connected_at": "2026-07-01T12:00:00Z",
  "revoked_at": null,
  "expires_at": null
}

metadata is OAuth-derived provider metadata (set by callback flows); connection_metadata is your operator-supplied merchant config; cert_metadata is parsed X.509 info for cert-auth connections.


GET /v1/connections

Lists the project's connections, newest first.

Query parameters

ParameterTypeDescription
limitintPage size
user_idstringFilter by end-user binding
server_idstringFilter by provider
statusstringpending | connected | revoked | expired

Response -- 200 OK

{
  "connections": [ { "id": "conn_abc123", "server_id": "asaas", "status": "connected", "...": "..." } ]
}

GET /v1/connections/:id

Returns one connection (same shape as create). 404 not_found for unknown or cross-tenant ids. The secret is never included.


POST /v1/connections/:id/revoke

Marks the connection revoked AND purges the backing vault rows atomically — after revoke, the credential is gone at both the status gate and the vault lookup. The row itself remains for audit.

Response -- 200 OK

{ "id": "conn_abc123", "status": "revoked" }

Revoking an already-revoked connection returns { "id": "...", "status": "revoked", "already": true }.


PATCH /v1/connections/:id/metadata

Updates connection_metadata (merchant config) without touching the credential. Same 64-key / 32 KB cap as create.

PUT /v1/connections/:id/webhook-secret

Sets or rotates the provider webhook signing secret bound to this connection (used to verify inbound POST /v1/webhooks/:server_id/:connection_id deliveries).

DELETE /v1/connections/:id

Hard-deletes the connection row (vault rows included). Prefer revoke in production — it preserves the audit trail.

Credential validation helpers also live here: POST /v1/connections/hmac-validate and POST /v1/connections/jwt-validate round-trip a candidate credential against the provider before you store it.


GET /v1/sessions/:id/connections

The session-scoped, read-only view: which providers this session can currently reach, with status and tool counts.

Auth required: Yes

curl example

curl https://api.codespar.dev/v1/sessions/ses_abc123/connections \
  -H "Authorization: Bearer csk_live_abc123..."

Response -- 200 OK

{
  "data": [
    {
      "id": "stripe",
      "name": "Stripe",
      "category": "payments",
      "country": "GLOBAL",
      "auth_type": "api_key",
      "connected": true,
      "tools_count": 8,
      "status": "ready"
    },
    {
      "id": "mercadopago",
      "name": "Mercado Pago",
      "category": "payments",
      "country": "BR",
      "auth_type": "oauth",
      "connected": true,
      "tools_count": 6,
      "status": "ready"
    }
  ],
  "total": 2,
  "session_id": "ses_abc123"
}

End-user OAuth (a customer connecting their own Mercado Pago / Shopify) runs through Connect Links (POST /v1/connect/start plus a hosted callback), not through a session endpoint. See Connect Links.

Error codes

CodeHTTPDescription
invalid_body / invalid_query400Request didn't match the schema
not_found404Connection unknown or cross-tenant
keys_mismatch400Path-secret object keys don't match the provider's declared names

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/connections

List the connections in this project

Query parameters

NameTypeRequiredDescription
limitintegerno
server_idstringno
status"pending" | "connected" | "revoked" | "expired"no
user_idstringno

Responses

StatusBodyDescription
200objectOK
400objectBad Request — the body or query did not match the schema.

Response 200

FieldTypeRequiredDescription
connectionsarray of objectyes

Example response

{
  "connections": [
    {
      "id": "obj_0000000000000000",
      "user_id": "user_0000000000000000",
      "server_id": "srv_0000000000000000",
      "auth_type": "string",
      "status": "pending",
      "connection_metadata": {},
      "cert_metadata": {},
      "created_at": "2026-01-15T12:00:00.000Z"
    }
  ]
}

Example request

curl -X GET https://api.codespar.dev/v1/connections \
  -H "Authorization: Bearer $CODESPAR_API_KEY"

POST /v1/connections

Register a provider key, or rotate the one already there

Request body

FieldTypeRequiredDescription
connection_metadataobjectno
display_namestringno
secretstring | objectyes
server_idstringyes
user_idstringno

Responses

StatusBodyDescription
200objectOK
201objectOK
400objectThe body did not parse, the owner could not be resolved, the server is not key-authenticated, or the secret's shape or keys do not match what the provider declares.
403objectService auth without x-codespar-user, or with a role below admin.
404objectNo such server in the catalog.
500objectThe provider's catalog row declares no path-secret refs, so there is nowhere to put the values. A seeding defect, not a bad request.
503objectThe vault or the connection write failed. Nothing was persisted.

Response 200

FieldTypeRequiredDescription
auth_typestringyesMirrors the catalog's auth_type at connect time: api_key, path_secret, cert, hmac_signed, jwt_ecdsa, two_header, oauth, cdp or none. Left open because the column is plain text.
cert_metadataobjectyesIssuer, subject, validity window and SHA-256 fingerprint parsed from the uploaded PEM at connect time. \{\} for every non-cert connection.
connected_atstring,null (date-time)yes
connection_metadataobjectyesOperator-supplied merchant config the router merges into upstream calls. \{\} when nothing was set.
created_atstring (date-time)yes
display_namestring,nullyes
expires_atstring,null (date-time)yes
idstringyesca_-prefixed. Globally unique, visible only inside the owning org and project.
metadataobject,nullyesProvider metadata the OAuth callback wrote (scope, refresh ref) or the provisioning projection wrote (account_id). Always present; null for a key registered through POST /v1/connections, which never sets it.
revoked_atstring,null (date-time)yes
server_idstringyesCatalog id of the provider this connection authenticates.
status"pending" | "connected" | "revoked" | "expired"yes
user_idstringyes

Example response

{
  "id": "obj_0000000000000000",
  "user_id": "user_0000000000000000",
  "server_id": "srv_0000000000000000",
  "auth_type": "string",
  "status": "pending",
  "connection_metadata": {},
  "cert_metadata": {},
  "created_at": "2026-01-15T12:00:00.000Z"
}

Example request

curl -X POST https://api.codespar.dev/v1/connections \
  -H "Authorization: Bearer $CODESPAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "server_id": "srv_0000000000000000",
       "secret": "string",
       "display_name": "Example",
       "user_id": "user_0000000000000000",
       "connection_metadata": {}
     }'

GET /v1/connections/engine/{run_id}/status

Poll a browser-driven signup run

Path parameters

NameTypeRequiredDescription
run_idstringyes

Responses

StatusBodyDescription
200objectOK
404objectNo run with that id inside the caller's org and project.
410objectThe paused run expired before it was resumed.

Response 200

FieldTypeRequiredDescription
code"flow_failed" | "capacity" | "no_credential_captured" | "probe_failed" | "drive_deadline_exceeded" | "provider_account_not_registered" | "drive_stalled" | "resume_inputs_unavailable"noWhy the run failed. A stored value outside this vocabulary is reported as absent rather than passed through, so a failed run can render as its status alone.
connection_idstringnoThe ca_ id of the connection the run produced. Present once the run reaches provisioned.
failed_step_idstringno
probe_resultnoResult of the post-provision reachability probe, when one ran.
promptstringnoPresent while the run waits on the customer. Fallback copy when the modal has none of its own.
status"running" | "needs_verification" | "provisioned" | "failed"yes
verificationobjectnoResolved from the provider's public descriptor. Present only while status is needs_verification.

Example response

{
  "status": "running",
  "prompt": "string",
  "verification": {
    "mechanism": "code",
    "resend": true
  },
  "connection_id": "conn_0000000000000000",
  "code": "flow_failed",
  "failed_step_id": "failedstep_0000000000000000"
}

Example request

curl -X GET https://api.codespar.dev/v1/connections/engine/{run_id}/status \
  -H "Authorization: Bearer $CODESPAR_API_KEY"

POST /v1/connections/start

Begin the Connect Link OAuth flow for a provider

Request body

FieldTypeRequiredDescription
redirect_uristring (uri)yes
scopesstringno
server_idstringyes
user_idstringyes

Responses

StatusBodyDescription
200objectOK
400objectBad Request — the body or query did not match the schema.
404objectThe provider has no OAuth configuration in the catalog.
500objectThe platform's OAuth client credential is not seeded for this provider. A configuration defect on our side.

Response 200

FieldTypeRequiredDescription
authorize_urlstring (uri)yesSend the user here. Carries client_id, our callback as redirect_uri, the state token, response_type=code and the resolved scopes.
expires_atstring (date-time)yesTen minutes after the call. A callback arriving later is refused.
link_tokenstringyesSingle-use state token, also embedded in authorize_url.

Example response

{
  "link_token": "string",
  "authorize_url": "https://example.com/hook",
  "expires_at": "2026-01-15T12:00:00.000Z"
}

Example request

curl -X POST https://api.codespar.dev/v1/connections/start \
  -H "Authorization: Bearer $CODESPAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "server_id": "srv_0000000000000000",
       "user_id": "user_0000000000000000",
       "redirect_uri": "https://example.com/hook",
       "scopes": "string"
     }'

POST /v1/connections/subaccount/{id}/revoke

Revoke a provisioned subaccount and try to delete it upstream

Path parameters

NameTypeRequiredDescription
idstringyesA ca_ connection id, or a pr_ provisioning record id on the operator-internal path.

Responses

StatusBodyDescription
200objectOK
403objectThis is a write, so it carries a role floor: a service-auth caller must send x-codespar-user and hold admin or above.
404objectNo connection or operator-internal record with that id is reachable by this caller.
500objectThe revoke threw unexpectedly.
503objectThe internal phase failed and left nothing changed. Retry.

Response 200

FieldTypeRequiredDescription
alreadytruenoPresent when the subaccount was already revoked. Nothing changed.
connection_idstringyesThe connection projection's id, or the provisioning record's id when there is no projection.
record_idstringyes
status"revoked"yes
upstream"deleted" | "delete_failed" | "not_applicable" | "orphaned"yesWhat happened at the provider. delete_failed and orphaned mean an account may still exist there; the local credential is gone either way.

Example response

{
  "status": "revoked",
  "record_id": "record_0000000000000000",
  "connection_id": "conn_0000000000000000",
  "upstream": "deleted",
  "already": true
}

Example request

curl -X POST https://api.codespar.dev/v1/connections/subaccount/{id}/revoke \
  -H "Authorization: Bearer $CODESPAR_API_KEY"

GET /v1/connections/subaccount/{id}/status

Read whether a provisioned subaccount can transact yet

Path parameters

NameTypeRequiredDescription
idstringyesA ca_ connection id, or a pr_ provisioning record id on the operator-internal path.

Responses

StatusBodyDescription
200objectOK
404objectNo connection or operator-internal record with that id is reachable by this caller.
500objectThe status read threw unexpectedly.
502objectThe provider read did not produce a status. Usually the live call failed or timed out, and a retry is the right response. TWO OF THE CASES BEHIND THIS CODE ARE NOT TRANSIENT and retrying never clears them: the provider has no subaccount descriptor in this deployment, and no platform account credential is registered for it. Both are configuration defects on our side; error.message distinguishes them from a provider outage.

Response 200

FieldTypeRequiredDescription
account_refstringyesThe upstream account identifier. Empty string when the record never reached one.
capabilitiesobjectnoPer-capability activation states as the provider reports them, for example card_payments: "active".
charges_enabledbooleanyes
status"provisioned" | "revoked"yes

Example response

{
  "status": "provisioned",
  "charges_enabled": true,
  "capabilities": {},
  "account_ref": "string"
}

Example request

curl -X GET https://api.codespar.dev/v1/connections/subaccount/{id}/status \
  -H "Authorization: Bearer $CODESPAR_API_KEY"

GET /v1/connections/{id}

Read one connection

Path parameters

NameTypeRequiredDescription
idstringyesca_-prefixed connection id

Responses

StatusBodyDescription
200objectOK
404objectNot Found

Response 200

FieldTypeRequiredDescription
auth_typestringyesMirrors the catalog's auth_type at connect time: api_key, path_secret, cert, hmac_signed, jwt_ecdsa, two_header, oauth, cdp or none. Left open because the column is plain text.
cert_metadataobjectyesIssuer, subject, validity window and SHA-256 fingerprint parsed from the uploaded PEM at connect time. \{\} for every non-cert connection.
connected_atstring,null (date-time)yes
connection_metadataobjectyesOperator-supplied merchant config the router merges into upstream calls. \{\} when nothing was set.
created_atstring (date-time)yes
display_namestring,nullyes
expires_atstring,null (date-time)yes
idstringyesca_-prefixed. Globally unique, visible only inside the owning org and project.
metadataobject,nullyesProvider metadata the OAuth callback wrote (scope, refresh ref) or the provisioning projection wrote (account_id). Always present; null for a key registered through POST /v1/connections, which never sets it.
revoked_atstring,null (date-time)yes
server_idstringyesCatalog id of the provider this connection authenticates.
status"pending" | "connected" | "revoked" | "expired"yes
user_idstringyes

Example response

{
  "id": "obj_0000000000000000",
  "user_id": "user_0000000000000000",
  "server_id": "srv_0000000000000000",
  "auth_type": "string",
  "status": "pending",
  "connection_metadata": {},
  "cert_metadata": {},
  "created_at": "2026-01-15T12:00:00.000Z"
}

Example request

curl -X GET https://api.codespar.dev/v1/connections/{id} \
  -H "Authorization: Bearer $CODESPAR_API_KEY"

DELETE /v1/connections/{id}

Delete a revoked connection for good

Path parameters

NameTypeRequiredDescription
idstringyesca_-prefixed connection id

Responses

StatusBodyDescription
204No Content
404objectNot Found
409objectThe connection is still active. Revoke it first.

Example request

curl -X DELETE https://api.codespar.dev/v1/connections/{id} \
  -H "Authorization: Bearer $CODESPAR_API_KEY"

POST /v1/connections/{id}/revoke

Revoke a connection and destroy its stored credential

Path parameters

NameTypeRequiredDescription
idstringyesca_-prefixed connection id

Responses

StatusBodyDescription
200object | objectOK
404objectNot Found
503objectThe atomic flip and purge failed. Nothing changed; the connection is still usable. Retry.

Example response

{
  "id": "obj_0000000000000000",
  "user_id": "user_0000000000000000",
  "server_id": "srv_0000000000000000",
  "auth_type": "string",
  "status": "pending",
  "connection_metadata": {},
  "cert_metadata": {},
  "created_at": "2026-01-15T12:00:00.000Z"
}

Example request

curl -X POST https://api.codespar.dev/v1/connections/{id}/revoke \
  -H "Authorization: Bearer $CODESPAR_API_KEY"

PUT /v1/connections/{id}/webhook-secret

Seed or rotate the secret that verifies this provider's inbound webhooks

Path parameters

NameTypeRequiredDescription
idstringyesca_-prefixed connection id

Request body

FieldTypeRequiredDescription
secretstringyes

Responses

StatusBodyDescription
200objectOK
400objectThe body did not parse, or the provider has no inbound webhook adapter in this API.
404objectNot Found
503objectThe vault write failed. Any previously stored secret is untouched.

Response 200

FieldTypeRequiredDescription
connection_idstringyes
server_idstringyes
updatedbooleanyesTrue when a secret already existed under this ref and was replaced; false when this call seeded the first one.

Example response

{
  "connection_id": "conn_0000000000000000",
  "server_id": "srv_0000000000000000",
  "updated": true
}

Example request

curl -X PUT https://api.codespar.dev/v1/connections/{id}/webhook-secret \
  -H "Authorization: Bearer $CODESPAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "secret": "string"
     }'
Connections | CodeSpar