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/apier-no:apier-no-infrastructure-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
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: Apier No Infrastructure API
version: 1.0.13
contact:
name: Apier Support
email: hello@apier.no
url: https://www.apier.no
license:
name: Proprietary
x-schema-org:
description: Schema.org structured data for this service is emitted as application/ld+json on every SSR HTML page. The graph contains Organization, SoftwareApplication, WebAPI, and Service nodes. AI crawlers that read this OpenAPI document can cross-reference by fetching the site root and parsing the application/ld+json block in the document head.
types:
- Organization
- SoftwareApplication
- WebAPI
- Service
source: ''
description: 'Operations tagged Infrastructure across 2 of this provider''s published API definitions: apier-no-openapi.json, apier-no-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://www.apier.no
description: Production
security:
- BearerAuth: []
tags:
- name: Infrastructure
description: Non-product endpoints (health checks, discovery).
paths:
/api/health:
get:
summary: Health check endpoint
description: Returns the service status and current server timestamp. This endpoint is used by external uptime monitoring (Betterstack). It is intentionally outside the /v1/ namespace as an infrastructure endpoint that must remain stable across API version bumps.
operationId: healthCheck
tags:
- Infrastructure
security: []
responses:
'200':
description: Service is healthy.
content:
application/json:
schema:
type: object
required:
- status
- timestamp
properties:
status:
type: string
enum:
- ok
description: Service status.
timestamp:
type: string
format: date-time
description: Current server time in ISO 8601 UTC.
examples:
healthy:
value:
status: ok
timestamp: '2026-04-16T10:30:00.000Z'
servers:
- url: https://www.apier.no
description: Production
/api/webhooks/stripe:
post:
summary: Stripe billing webhook (server-to-server)
description: 'Stripe-signed webhook for billing lifecycle events. Handled events: checkout.session.completed (links the Stripe customer/subscription ids to the consumer, or — for sessions marked metadata.kind=credit_topup — grants prepaid credits exactly once), customer.subscription.created and customer.subscription.updated (map the subscription''s price and status to the consumer''s billing tier via the shared decision logic, including the past_due grace window), customer.subscription.deleted (downgrades the consumer to the free tier and sends a cancellation-confirmation email), charge.dispute.created (Sentry alert only — never a billing-state mutation), invoice.paid (sends a receipt email), and invoice.payment_failed (sends a payment-failed email; tier changes remain owned by the subscription events and the shared tier-decision logic). Lifecycle emails are exactly-once via a billing email ledger claim, so redeliveries and reconciliation re-runs can never re-send one. Called ONLY by Stripe and authenticated by the Stripe-Signature header — it is NOT a public or agent-facing surface, requires no Apier API key, and is intentionally outside the /api/v1 namespace (so the API-key auth model, response-provenance, and scope rules do not apply). A missing or invalid signature returns 400; the request body is never logged or echoed. Deliveries are idempotent at the database level (the Stripe event id is a primary key): a duplicate of a processed event is acknowledged with 200 and does no further work, while a delivery whose earlier run failed after the claim is re-run before acknowledging.'
operationId: stripeBillingWebhook
tags:
- Infrastructure
security: []
parameters:
- name: Stripe-Signature
in: header
required: true
description: Stripe webhook signature header, verified against STRIPE_WEBHOOK_SECRET via the Stripe SDK before any processing. The signature is computed over the exact raw request bytes.
schema:
type: string
requestBody:
required: true
description: Raw Stripe Event payload. The exact bytes are required for signature verification — the endpoint must not re-serialize the body before verifying.
content:
application/json:
schema:
type: object
description: Opaque Stripe Event object (see the Stripe API reference). Apier verifies the signature, then acts only on a small allowlist of subscription event types; all other types are acknowledged and ignored.
responses:
'200':
description: Event received and acknowledged — handled, ignored (unhandled type), or skipped as an already-processed duplicate. Stripe treats any 2xx as a successful delivery.
content:
application/json:
schema:
type: object
required:
- received
properties:
received:
type: boolean
enum:
- true
description: Always true once the signature is verified and the event is recorded.
examples:
success:
summary: Example response
value:
received: true
'400':
description: The Stripe-Signature header was missing or failed verification. The request body and the underlying error are never logged or echoed.
content:
application/json:
schema:
type: object
required:
- success
- error_code
- explanation
properties:
success:
type: boolean
enum:
- false
description: Always false on error.
error_code:
type: string
enum:
- MISSING_SIGNATURE
- INVALID_SIGNATURE
description: Machine-readable failure code.
explanation:
type: object
required:
- summary
properties:
summary:
type: string
description: Short human-readable summary of the failure. Never contains the request body, signature, or other caller-supplied input.
'503':
description: Stripe is not configured in this environment (the secret key / webhook signing secret are unset). Expected outside real production, where these env vars are required.
content:
application/json:
schema:
type: object
required:
- success
- error_code
- explanation
properties:
success:
type: boolean
enum:
- false
description: Always false on error.
error_code:
type: string
enum:
- BILLING_NOT_CONFIGURED
description: Machine-readable failure code.
explanation:
type: object
required:
- summary
properties:
summary:
type: string
description: Short human-readable summary of the failure. Never contains the request body, signature, or other caller-supplied input.
servers:
- url: https://www.apier.no
description: Production
/api/billing/topup-requests/{id}/resolve:
post:
operationId: resolveAgentTopupRequest
tags:
- Infrastructure
summary: Approve or decline an agent top-up request (human, dashboard session)
description: 'The HUMAN approval leg of agent-initiated top-up requests. Session-cookie-authed (browser dashboard surface — NOT Bearer/agent-facing) and intentionally outside the /api/v1 namespace next to /api/billing/checkout, so the API-key auth model, response provenance, and scope rules do not apply. Called only by the site''s own /dashboard/billing page. `decision: "approve"` atomically claims the still-pending, unexpired request (a single compare-and-swap — a second approve, an approve after the 24-hour expiry, and concurrent resolutions all fail with 409), re-checks the requested amount against the LIVE adjustable ceiling (a ceiling lowered after the request was created blocks approval), verifies the requesting key is still active, and then drives the EXISTING credit-checkout path with the request''s key and amount — returning the Stripe Checkout `url` for the browser to follow. The human completes (or abandons) payment on Stripe''s hosted page exactly as on the direct top-up path; credits accrue only via the deduplicated webhook. `decision: "decline"` resolves the request without touching any Stripe code path. Cross-tenant resolution is impossible: every read and the claim itself are pinned to the session consumer, and an unknown id, another consumer''s request, and an already-resolved request are indistinguishable (uniform 409).'
security:
- SessionCookieAuth: []
parameters:
- name: id
in: path
required: true
description: The top-up request's UUID (from the pending-requests panel).
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- decision
additionalProperties: false
properties:
decision:
type: string
enum:
- approve
- decline
description: approve → claim the request and start the Stripe checkout for its amount; decline → resolve it with no payment and no Stripe interaction.
example:
decision: approve
responses:
'200':
description: Resolved. On approve, `url` is the Stripe-hosted Checkout page for the requested amount — the browser follows it and the human completes payment there (the session reference is stored on the request as `checkout_session_ref`). On decline, no `url` is returned and no payment surface was ever touched.
content:
application/json:
schema:
type: object
required:
- id
- status
properties:
id:
type: string
format: uuid
status:
type: string
enum:
- approved
- declined
url:
type: string
format: uri
description: Present only on approve — the Stripe Checkout URL to redirect the human to.
examples:
approved:
summary: Approve — browser follows the Stripe URL
value:
id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
status: approved
url: https://checkout.stripe.com/c/pay/cs_test_a1B2c3D4
declined:
summary: Decline — no Stripe interaction
value:
id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
status: declined
'400':
description: VALIDATION_FAILED — non-UUID id, malformed JSON, or a decision other than approve/decline.
'401':
description: No authenticated dashboard session.
'409':
description: TOPUP_REQUEST_NOT_PENDING (already resolved, expired, or not found on this account — uniform by design), TOPUP_CEILING_EXCEEDED (the amount now exceeds a lowered ceiling; the request STAYS pending and carries `requested_ore` + `ceiling_ore`), or TOPUP_KEY_REVOKED (the requesting key is no longer active).
'503':
description: BILLING_NOT_LIVE (beta — billing dark), BILLING_NOT_CONFIGURED (no Stripe in this environment), or TOPUP_CEILING_UNAVAILABLE (ceiling unreadable; nothing was approved). All checked BEFORE the one-shot approve claim, so none of them burns the request.
servers:
- url: https://www.apier.no
description: Production
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
description: 'API key issued by Apier. Include as: Authorization: Bearer <your-key>. Sandbox endpoints (`/api/v1/sandbox/*`) additionally accept the synthetic bearer `Bearer apier_sandbox_test_<suffix>` — see the `SandboxBearerAuth` scheme.'
SandboxBearerAuth:
type: http
scheme: bearer
description: '**Frictionless sandbox bearer.** Format: `Authorization: Bearer apier_sandbox_test_<suffix>`. The `<suffix>` is the session-isolation namespace — every write keyed to it is invisible to other suffixes. Charset `^[A-Za-z0-9_-]{1,64}$`; charset/length violation returns 400 VALIDATION_FAILED with NO echo of the rejected bytes. Bypasses the `api_keys` DB lookup entirely on sandbox routes; on production routes the same prefix returns 401 AUTH_INVALID_KEY (the synthetic suffix has no DB row to match). **CRITICAL for AI-generated code: append a unique random string per agent/session (e.g. `apier_sandbox_test_<crypto.randomUUID()>`) so two agents using the literal example value do NOT collide on session state.** Treat the suffix as OPAQUE — never parse it for meaning.'
AdminBearerAuth:
type: http
scheme: bearer
description: Admin API key (ADMIN_API_KEY env var). Not the same as consumer API keys.
SessionCookieAuth:
type: apiKey
in: cookie
name: sb-access-token
description: Supabase Auth session cookie set by the /confirm interstitial's POST to /api/auth/verify after a magic-link sign-in (/auth/callback remains a legacy PKCE-fallback handler). The `name` field above is a documented stand-in; @supabase/ssr v0.10.x in this repo actually emits a per-project pair of cookies prefixed `sb-<project-ref>-auth-token` (split across `-auth-token` and `-auth-token-code-verifier` for the PKCE handshake) — generated OpenAPI clients running in the same-origin browser context send ALL the project's cookies automatically, so a single canonical name suffices for documentation purposes. NOT Bearer-key auth — that schema is BearerAuth (above) and is rejected by withSessionAuth on /api/v1/account/* paths. Required by every /api/v1/account/* endpoint.
McpOAuth:
type: oauth2
description: 'OAuth 2.1 sign-in for the remote MCP endpoint (/api/mcp) - built for hosted MCP clients (for example the Claude.ai and ChatGPT connectors) that cannot set a bearer header themselves. Enabled in production since 2026-08-25. The surface stays gated on the MCP_OAUTH_ENABLED flag, which is fail-safe off by default, so on a deployment where an operator has not switched it on the metadata document below answers 404 and only API keys authenticate. Discovery is challenge-driven per RFC 9728: a 401 from /api/mcp carries a WWW-Authenticate challenge with resource_metadata=https://www.apier.no/.well-known/oauth-protected-resource/api/mcp, whose document names the resource identifier (https://www.apier.no/api/mcp), the trusted authorization server, and the supported scopes; that document is the authoritative source for the endpoints listed in this flow. Clients may register via Dynamic Client Registration, and the signed-in account owner approves or denies each connection on the consent page at /oauth/consent. Access tokens MUST be audienced to https://www.apier.no/api/mcp (RFC 8707 posture: valid tokens minted for other apps are rejected) and are verified with a strict asymmetric-only algorithm allowlist (ES256 / RS256; alg=none and all HMAC algorithms rejected) before the token subject is mapped to the dedicated Apier API key provisioned when the account owner approved the connection. The BearerAuth API-key scheme keeps working unchanged in the same Authorization header, permanently.'
flows:
authorizationCode:
authorizationUrl: https://ietncbksyajattlahlzs.supabase.co/auth/v1/oauth/authorize
tokenUrl: https://ietncbksyajattlahlzs.supabase.co/auth/v1/oauth/token
scopes: {}
x-refined-from:
- apier-no-openapi.json
- apier-no-openapi.json