Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/argus-town:argus-town-syncs-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Argus Syncs API
version: '1'
description: 'Argus API v1: spend, balances and rate-limit headroom across the APIs you pay for.
Authenticate reads with an `api` key as `Authorization: Bearer `. Every key sees one project.
Operations marked `x-access: session` are for the signed-in web app; API keys get `session_required`.
Operations marked `x-web: true` also accept the web app''s session, which API clients never use.
Operations with `x-mcp-key-types` are also MCP tools of the same name at `POST https://mcp.argus.town`, for keys of those types.
Send events with a source secret (`Authorization: Bearer argus_src_...` plus `Argus-Source`) or HMAC headers. A source credential can write events and read nothing; an API key cannot write events.
Responses are bare resources with an `object` tag; lists are `{object: "list", data, has_more, next_cursor}`.
Errors are `{error: {type, code, message, param, doc_url, next_step, request_id}}` with real HTTP statuses.
Unknown query parameters are rejected. Ids are prefixed (`conn_...`); bare ids are accepted on input.
Within v1 changes are additive: ignore fields you do not recognise.'
servers:
- url: https://api.argus.town
tags:
- name: Syncs
paths:
/v1/connections/{id}/syncs:
post:
operationId: syncs_create
tags:
- Syncs
summary: Refresh a connection
description: 'Queue an immediate refresh of balance, usage and plan, and get a sync to poll with `GET /v1/syncs/{id}`. At most one refresh is queued per connection a minute, whatever state the last one is in: a request inside that window returns the latest sync instead of queueing another. Telemetry-only and suspended connections have nothing to poll: 409 `connection_not_pollable`.'
security:
- bearerAuth: []
x-access: api_key
x-web: true
x-mcp-key-types:
- api
- mcp
parameters:
- name: id
in: path
required: true
description: Connection id, with or without the `conn_` prefix.
schema:
type: string
- name: Idempotency-Key
in: header
required: false
description: '1 to 255 printable ASCII characters. A retry with the same key and body replays the first response (`Idempotent-Replayed: true`) for 24 hours; the same key with a different body is a 409, and so is a duplicate that arrives while the first request is still running.'
schema:
type: string
responses:
'202':
description: Success.
content:
application/json:
schema:
$ref: '#/components/schemas/Sync'
examples:
queued:
summary: queued
value:
object: sync
id: sync_5d0c7a21-8e4b-4f6a-9c13-2b7e1a90d4f8
kind: refresh
status: queued
started_at: '2026-10-01T09:30:00.000Z'
finished_at: null
records_written: 0
error: null
'400':
description: 'Error. Codes: invalid_idempotency_key, unknown_parameter, missing_parameter.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'401':
description: 'Error. Codes: missing_credentials, invalid_api_key, session_expired.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'403':
description: 'Error. Codes: key_type_not_allowed, session_required, csrf_check_failed.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'404':
description: 'Error. Codes: connection_not_found.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'409':
description: 'Error. Codes: connection_not_pollable, idempotency_key_reused, idempotency_key_in_progress.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples:
telemetry only:
summary: telemetry only
value:
error:
type: conflict
code: connection_not_pollable
message: This connection only receives telemetry, so there is nothing to refresh.
param: null
doc_url: https://argus.town/docs/errors#connection_not_pollable
request_id: null
'429':
description: 'Error. Codes: rate_limit_exceeded.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
'500':
description: 'Error. Codes: internal_error.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
x-argus-examples:
- name: queued
request:
method: POST
path: /v1/connections/{connection}/syncs
status: 202
- name: telemetry only
request:
method: POST
path: /v1/connections/{id}/syncs
status: 409
get:
operationId: syncs_list
tags:
- Syncs
summary: List refreshes
description: Refreshes requested for the connection, newest first. A sync is `queued`, `running` once some of its runs have reported, then `success`, `partial` or `error`. A transient provider error reads `partial` until the retry lands; a sync the queue never finished is closed after 30 minutes with what it has.
security:
- bearerAuth: []
x-access: api_key
parameters:
- name: id
in: path
required: true
description: Connection id, with or without the `conn_` prefix.
schema:
type: string
- name: limit
in: query
required: false
description: Page size. Default 25.
schema:
$ref: '#/components/schemas/Int'
description: a number between 1 and 200
title: between(1, 200)
minimum: 1
maximum: 200
- name: cursor
in: query
required: false
description: Opaque cursor from a previous page's `next_cursor`.
schema:
$ref: '#/components/schemas/NonEmptyString'
responses:
'200':
description: Success.
content:
application/json:
schema:
$ref: '#/components/schemas/SyncList'
examples:
history:
summary: history
value:
object: list
data:
- object: sync
id: sync_5d0c7a21-8e4b-4f6a-9c13-2b7e1a90d4f8
kind: refresh
status: queued
started_at: '2026-10-01T09:30:00.000Z'
finished_at: null
records_written: 0
error: null
has_more: false
next_cursor: null
'400':
description: 'Error. Codes: invalid_parameter, invalid_cursor, unknown_parameter.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'401':
description: 'Error. Codes: missing_credentials, invalid_api_key.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'403':
description: 'Error. Codes: key_type_not_allowed.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'404':
description: 'Error. Codes: connection_not_found.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'429':
description: 'Error. Codes: rate_limit_exceeded.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
'500':
description: 'Error. Codes: internal_error.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
x-argus-examples:
- name: history
request:
method: GET
path: /v1/connections/{connection}/syncs?limit=5
status: 200
/v1/syncs/{id}:
get:
operationId: syncs_get
tags:
- Syncs
summary: Get a sync
description: One refresh, or one scheduled run as listed under a connection's `sync_runs` expansion.
security:
- bearerAuth: []
x-access: api_key
x-web: true
x-mcp-key-types:
- api
parameters:
- name: id
in: path
required: true
description: Sync id, with or without the `sync_` prefix.
schema:
type: string
responses:
'200':
description: Success.
content:
application/json:
schema:
$ref: '#/components/schemas/Sync'
examples:
queued:
summary: queued
value:
object: sync
id: sync_5d0c7a21-8e4b-4f6a-9c13-2b7e1a90d4f8
kind: refresh
status: queued
started_at: '2026-10-01T09:30:00.000Z'
finished_at: null
records_written: 0
error: null
'400':
description: 'Error. Codes: unknown_parameter, missing_parameter.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'401':
description: 'Error. Codes: missing_credentials, invalid_api_key, session_expired.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'403':
description: 'Error. Codes: key_type_not_allowed, session_required, csrf_check_failed.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'404':
description: 'Error. Codes: sync_not_found.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'429':
description: 'Error. Codes: rate_limit_exceeded.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
'500':
description: 'Error. Codes: internal_error.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
x-argus-examples:
- name: queued
request:
method: GET
path: /v1/syncs/{sync}
status: 200
components:
schemas:
NextStep:
type: object
required:
- hint
properties:
hint:
type: string
method:
type: string
href:
type: string
additionalProperties: true
SyncList:
type: object
required:
- object
- data
- has_more
- next_cursor
properties:
object:
type: string
enum:
- list
data:
type: array
items:
$ref: '#/components/schemas/Sync'
has_more:
type: boolean
next_cursor:
anyOf:
- type: string
- type: 'null'
additionalProperties: true
ErrorResponse:
type: object
required:
- error
properties:
error:
type: object
required:
- type
- code
- message
- param
- doc_url
- request_id
properties:
type:
type: string
enum:
- invalid_request
- authentication_error
- permission_error
- not_found
- conflict
- rate_limited
- plan_limit
- upstream_error
- api_error
code:
type: string
enum:
- unknown_parameter
- invalid_parameter
- invalid_cursor
- method_not_allowed
- missing_credentials
- invalid_api_key
- invalid_request_body
- missing_parameter
- invalid_idempotency_key
- payload_too_large
- too_many_events
- no_valid_events
- missing_source_credentials
- invalid_source_credentials
- timestamp_stale
- idempotency_key_reused
- idempotency_key_in_progress
- too_many_auth_failures
- origin_not_allowed
- key_type_not_allowed
- not_found
- provider_not_found
- connection_not_found
- sync_not_found
- connect_link_not_found
- alert_rule_not_found
- negotiated_pricing_not_found
- provider_not_connectable
- credential_invalid
- provider_unreachable
- label_conflict
- connection_not_pollable
- quota_exceeded
- session_required
- session_expired
- csrf_check_failed
- rate_limit_exceeded
- internal_error
message:
type: string
param:
anyOf:
- type: string
- type: 'null'
doc_url:
type: string
next_step:
$ref: '#/components/schemas/NextStep'
details:
type: object
required: []
properties: {}
additionalProperties:
$id: /schemas/unknown
title: unknown
request_id:
anyOf:
- type: string
- type: 'null'
additionalProperties: true
additionalProperties: true
Int:
type: integer
description: an integer
title: int
Sync:
type: object
required:
- object
- id
- kind
- status
- started_at
- finished_at
- records_written
- error
properties:
object:
type: string
enum:
- sync
id:
type: string
kind:
type: string
status:
type: string
started_at:
type: string
format: date-time
finished_at:
anyOf:
- type: string
format: date-time
- type: 'null'
records_written:
type: number
error:
anyOf:
- type: string
- type: 'null'
additionalProperties: true
NonEmptyString:
type: string
description: a non empty string
title: nonEmptyString
minLength: 1
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: An `api` key.
sessionCookie:
type: apiKey
in: cookie
name: argus_session
description: The signed-in web app session. Operations that need it refuse every API key with `session_required`.
sourceSecret:
type: http
scheme: bearer
description: 'A source secret (`argus_src_...`), sent with the `Argus-Source` header. Write-only: it can send events and read nothing.'
sourceSignature:
type: apiKey
in: header
name: X-Argus-Signature
description: Hex HMAC-SHA256 of the timestamp, a dot and the raw body, keyed with the source secret, sent with `X-Argus-Source` and `X-Argus-Timestamp` (epoch ms, within 5 minutes).
x-error-codes:
unknown_parameter:
type: invalid_request
status: 400
description: The request has a query parameter this endpoint does not accept.
invalid_parameter:
type: invalid_request
status: 400
description: A parameter has a value this endpoint cannot use. `param` names it.
invalid_cursor:
type: invalid_request
status: 400
description: The cursor is malformed or does not belong to this list. Start again without it.
method_not_allowed:
type: invalid_request
status: 405
description: The path exists but not for this HTTP method. The Allow header lists the methods.
missing_credentials:
type: authentication_error
status: 401
description: No Authorization header was sent.
invalid_api_key:
type: authentication_error
status: 401
description: The key is unknown, revoked, or not an API key.
invalid_request_body:
type: invalid_request
status: 400
description: The body is not a JSON object (or, on `/v1/events`, not an event or an `events` array), or it is empty where fields are required.
missing_parameter:
type: invalid_request
status: 400
description: A required body field or header is missing. `param` names it.
invalid_idempotency_key:
type: invalid_request
status: 400
description: The Idempotency-Key header must be 1 to 255 printable ASCII characters.
payload_too_large:
type: invalid_request
status: 413
description: The body is over 1,000,000 bytes. Split the batch.
too_many_events:
type: invalid_request
status: 413
description: A batch holds at most 1,000 events. Split it.
no_valid_events:
type: invalid_request
status: 422
description: Every event in the batch was rejected, so nothing was queued. Send the same body to `POST /v1/events/validate` for each event's reason.
missing_source_credentials:
type: authentication_error
status: 401
description: 'No source credential was sent. Use `Authorization: Bearer <source secret>` with `Argus-Source: <source id>`, or the HMAC headers `X-Argus-Source`, `X-Argus-Timestamp` and `X-Argus-Signature`.'
invalid_source_credentials:
type: authentication_error
status: 401
description: The source is unknown or revoked, or the bearer secret or HMAC signature is wrong (sign the timestamp, a dot and the raw body, hex HMAC-SHA256). The cases are not distinguished.
timestamp_stale:
type: authentication_error
status: 401
description: The signed timestamp (epoch milliseconds) is more than 5 minutes from server time.
idempotency_key_reused:
type: conflict
status: 409
description: This Idempotency-Key was already used with a different request body or source. Use a new key for a new request.
idempotency_key_in_progress:
type: conflict
status: 409
description: A request with this Idempotency-Key is still running. Retry with the same key after a moment; it replays the response once the first request finishes.
too_many_auth_failures:
type: rate_limited
status: 429
description: Too many failed authentication attempts from this address. Wait `Retry-After` seconds. Valid credentials keep working from an address over budget, except that a credential the server has not seen recently gets only a small number of lookups per window, tracked per server instance; a client sharing an address with an attacker can be briefly locked out.
origin_not_allowed:
type: permission_error
status: 403
description: A browser Origin that is not allow-listed called the MCP server. Non-browser clients send no Origin.
key_type_not_allowed:
type: permission_error
status: 403
description: This key's type cannot call this endpoint.
not_found:
type: not_found
status: 404
description: No such endpoint.
provider_not_found:
type: not_found
status: 404
description: No provider has this slug.
connection_not_found:
type: not_found
status: 404
description: No connection with this id in the key's project. When a request body names the connection (`param` says where) the status is 422.
sync_not_found:
type: not_found
status: 404
description: No sync with this id in the key's project.
connect_link_not_found:
type: not_found
status: 404
description: No connect link with this id in the key's project.
alert_rule_not_found:
type: not_found
status: 404
description: No alert rule with this id in the key's project.
negotiated_pricing_not_found:
type: not_found
status: 404
description: The project has no negotiated pricing for this provider.
provider_not_connectable:
type: invalid_request
status: 422
description: The provider is unknown or Argus cannot poll it with a credential (telemetry only).
credential_invalid:
type: invalid_request
status: 422
description: The provider rejected the credential. `message` carries the provider's reason; the credential is never echoed.
provider_unreachable:
type: upstream_error
status: 502
description: Argus could not reach the provider to check the credential. Retry.
label_conflict:
type: conflict
status: 409
description: Another connection to this provider already has this label. Update that connection instead, or choose another label.
connection_not_pollable:
type: conflict
status: 409
description: The connection has no credential to poll with (telemetry only) or is suspended, so there is nothing to sync.
quota_exceeded:
type: plan_limit
status: 409
description: The project reached a limit on this kind of resource. `details` holds `resource`, `limit` and `used`.
session_required:
type: permission_error
status: 403
description: This operation needs a signed-in session in the Argus app; API keys cannot perform it.
session_expired:
type: authentication_error
status: 401
description: The web app's session is missing, expired or signed out. Only the signed-in web app sees it.
csrf_check_failed:
type: permission_error
status: 403
description: 'A web-app write did not come from the app itself: it lacks `x-argus-csrf`, or its `Origin` or `Sec-Fetch-Site` is not the app''s. API keys never see it.'
rate_limit_exceeded:
type: rate_limited
status: 429
description: The key exceeded its request budget. Wait `Retry-After` seconds.
internal_error:
type: api_error
status: 500
description: Something failed on our side. Retry; quote `request_id` if it persists.