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-start-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 Start 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: Start
paths:
/v1:
get:
operationId: index_get
tags:
- Start
summary: API index
description: 'Self-describing entry point: where the contract, error catalog and MCP endpoint live, how to authenticate, and the first authenticated call.'
security: []
x-access: public
parameters: []
responses:
'200':
description: Success.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiIndex'
examples:
index:
summary: index
value:
object: api
version: v1
status: ok
links:
documentation: https://argus.town/docs/api
openapi: /v1/openapi.json
errors: /v1/errors
providers: /v1/providers
mcp: https://mcp.argus.town
authentication:
scheme: bearer
key_type: api
create_key_url: https://argus.town/settings
first_call:
method: GET
href: /v1/project
curl: 'curl -s https://api.argus.town/v1/project -H "Authorization: Bearer $ARGUS_API_KEY"'
next_steps:
- rel: list_providers
method: GET
href: /v1/providers
why: See which providers Argus covers, no key needed.
x-argus-examples:
- name: index
request:
method: GET
path: /v1
status: 200
/v1/device/code:
post:
operationId: device_code
tags:
- Start
summary: Start device login
description: 'For an agent with no credentials: ask for access, show the human `verification_uri_complete`, and poll `POST /v1/device/token`. The human signs in, picks the project and approves the scopes listed; nothing is issued before that. `api` (alias `read`) is an API key, which can read spend and also create and update connections, alert rules and negotiated pricing in the approved project; `ingest` is a telemetry source; `mcp` is an MCP key. Without `scopes`: `api` and `ingest`. Rate limited per address.'
security: []
x-access: public
parameters: []
requestBody:
required: true
description: Optional client name and scopes.
content:
application/json:
schema:
$ref: '#/components/schemas/DeviceCodeBody'
responses:
'201':
description: Success.
content:
application/json:
schema:
$ref: '#/components/schemas/DeviceCode'
examples:
api and ingest:
summary: api and ingest
value:
object: device_code
device_code: argus_dev_3b9f0c5e1a7d4826b0c9e3f5a1d7b2c84e6f0a9d3c5b7e1f
user_code: BCDF-GHJK
verification_uri: https://argus.town/device
verification_uri_complete: https://argus.town/device?code=BCDF-GHJK
expires_in: 900
interval: 7
'400':
description: 'Error. Codes: invalid_request_body, invalid_parameter.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples:
unknown scope:
summary: unknown scope
value:
error:
type: invalid_request
code: invalid_parameter
message: 'Invalid value for "scopes[0]": Expected "api" | "read" | "ingest" | "mcp", actual "admin"'
param: scopes[0]
doc_url: https://argus.town/docs/errors#invalid_parameter
request_id: null
'413':
description: 'Error. Codes: payload_too_large.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
x-argus-examples:
- name: api and ingest
request:
method: POST
path: /v1/device/code
body:
client_name: my-agent
scopes:
- api
- ingest
status: 201
- name: unknown scope
request:
method: POST
path: /v1/device/code
body:
scopes:
- admin
status: 400
/v1/device/token:
post:
operationId: device_token
tags:
- Start
summary: Poll device login
description: 'Poll with the `device_code` until `status` leaves `pending`. On `approved` the credentials are returned once (`api_key`, `source.secret`, `mcp_key` as requested) together with the project; later polls say `consumed`. `denied`, `expired`, `consumed` and `invalid` are final: start again. Rate limited per code and, for unknown codes, per address.'
security: []
x-access: public
parameters: []
requestBody:
required: true
description: The device code from the first step.
content:
application/json:
schema:
$ref: '#/components/schemas/DeviceTokenBody'
responses:
'200':
description: Success.
content:
application/json:
schema:
$ref: '#/components/schemas/DeviceToken'
examples:
pending:
summary: pending
value:
object: device_token
status: pending
next_steps:
- rel: poll
method: POST
href: /v1/device/token
why: Not approved yet. Poll again in 7 seconds.
unknown code:
summary: unknown code
value:
object: device_token
status: invalid
next_steps:
- rel: restart
method: POST
href: /v1/device/code
why: This code cannot yield credentials. Start again.
'400':
description: 'Error. Codes: invalid_request_body, invalid_parameter, missing_parameter.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
'413':
description: 'Error. Codes: payload_too_large.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
x-argus-examples:
- name: pending
request:
method: POST
path: /v1/device/token
body:
device_code: '{device_code.device_code}'
status: 200
- name: unknown code
request:
method: POST
path: /v1/device/token
body:
device_code: argus_dev_nope
status: 200
/v1/openapi.json:
get:
operationId: openapi_get
tags:
- Start
summary: OpenAPI document
description: This contract as OpenAPI 3.1, generated from the operation table.
security: []
x-access: public
parameters: []
responses:
'200':
description: Success.
content:
application/json:
schema:
$ref: '#/components/schemas/OpenApiDocument'
examples: {}
x-argus-examples: []
/v1/errors:
get:
operationId: errors_list
tags:
- Start
summary: Error catalog
description: Every error code the API returns, with its type and HTTP status.
security: []
x-access: public
parameters:
- 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/ErrorCodeList'
examples:
first code:
summary: first code
value:
object: list
data:
- object: error_code
code: connection_not_found
type: not_found
status: 404
description: No connection with this id in the key's project.
doc_url: https://argus.town/docs/errors#connection_not_found
has_more: true
next_cursor: WyJjb25uZWN0aW9uX25vdF9mb3VuZCJd
'400':
description: 'Error. Codes: invalid_parameter, invalid_cursor.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples: {}
x-argus-examples:
- name: first code
request:
method: GET
path: /v1/errors?limit=1
status: 200
components:
schemas:
ErrorCodeList:
type: object
required:
- object
- data
- has_more
- next_cursor
properties:
object:
type: string
enum:
- list
data:
type: array
items:
$ref: '#/components/schemas/ErrorCodeInfo'
has_more:
type: boolean
next_cursor:
anyOf:
- type: string
- type: 'null'
additionalProperties: true
NextStep:
type: object
required:
- hint
properties:
hint:
type: string
method:
type: string
href:
type: string
additionalProperties: true
DeviceCode:
type: object
required:
- object
- device_code
- user_code
- verification_uri
- verification_uri_complete
- expires_in
- interval
properties:
object:
type: string
enum:
- device_code
device_code:
type: string
user_code:
type: string
verification_uri:
type: string
verification_uri_complete:
type: string
expires_in:
type: number
interval:
type: number
additionalProperties: true
OpenApiDocument:
type: object
required: []
properties: {}
additionalProperties:
$id: /schemas/unknown
title: unknown
description: An OpenAPI 3.1 document.
NextStepItem:
type: object
required:
- rel
- method
- href
- why
properties:
rel:
type: string
method:
type: string
href:
type: string
why:
type: string
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
NonEmptyString:
type: string
description: a non empty string
title: nonEmptyString
minLength: 1
ApiIndex:
type: object
required:
- object
- version
- status
- links
- authentication
- first_call
- next_steps
properties:
object:
type: string
enum:
- api
version:
type: string
enum:
- v1
status:
type: string
enum:
- ok
links:
type: object
required:
- documentation
- openapi
- errors
- providers
- mcp
properties:
documentation:
type: string
openapi:
type: string
errors:
type: string
providers:
type: string
mcp:
type: string
additionalProperties: true
authentication:
type: object
required:
- scheme
- key_type
- create_key_url
properties:
scheme:
type: string
enum:
- bearer
key_type:
type: string
enum:
- api
create_key_url:
type: string
additionalProperties: true
first_call:
type: object
required:
- method
- href
- curl
properties:
method:
type: string
href:
type: string
curl:
type: string
additionalProperties: true
next_steps:
type: array
items:
$ref: '#/components/schemas/NextStepItem'
additionalProperties: true
DeviceCodeBody:
type: object
required: []
properties:
client_name:
type: string
description: a string at most 60 character(s) long
title: maxLength(60)
minLength: 1
maxLength: 60
scopes:
type: array
items:
type: string
enum:
- api
- read
- ingest
- mcp
description: '`api` (alias `read`): an API key; `ingest`: a telemetry source; `mcp`: an MCP key. Default: `api` and `ingest`.'
title: maxItems(4)
minItems: 1
maxItems: 4
additionalProperties: true
Int:
type: integer
description: an integer
title: int
ErrorCodeInfo:
type: object
required:
- object
- code
- type
- status
- description
- doc_url
properties:
object:
type: string
enum:
- error_code
code:
type: string
type:
type: string
status:
type: number
description:
type: string
doc_url:
type: string
additionalProperties: true
DeviceToken:
type: object
required:
- object
- status
- next_steps
properties:
object:
type: string
enum:
- device_token
status:
type: string
enum:
- pending
- approved
- denied
- consumed
- expired
- invalid
project:
type: object
required:
- object
- id
- name
properties:
object:
type: string
enum:
- project
id:
type: string
name:
anyOf:
- type: string
- type: 'null'
additionalProperties: true
api_key:
type: string
mcp_key:
type: string
source:
type: object
required:
- object
- id
- secret
properties:
object:
type: string
enum:
- source
id:
type: string
secret:
type: string
additionalProperties: true
next_steps:
type: array
items:
$ref: '#/components/schemas/NextStepItem'
additionalProperties: true
DeviceTokenBody:
type: object
required:
- device_code
properties:
device_code:
type: string
description: a string at most 200 character(s) long
title: maxLength(200)
minLength: 1
maxLength: 200
additionalProperties: true
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.