APIFold

API Reference

All API endpoints are available at /api and require authentication.

Authentication

Include your Clerk session token in the Authorization header:

Authorization: Bearer <session-token>

All authenticated routes are protected by Clerk middleware. Unauthenticated requests receive a 401 response.

Response Format

All responses follow a consistent envelope:

// Success
{
  "success": true,
  "data": T,
  "error": null,
  "meta": { "total": 100, "page": 1, "limit": 20, "hasMore": true }
}
 
// Error
{
  "success": false,
  "data": null,
  "error": { "code": "NOT_FOUND", "message": "Resource not found" }
}

Error Codes

CodeHTTP StatusDescription
VALIDATION_ERROR400Invalid request body or parameters
AUTH_ERROR401Missing or invalid authentication
FORBIDDEN403Insufficient permissions
NOT_FOUND404Resource does not exist
CONFLICT409Resource already exists
RATE_LIMIT429Too many requests
INTERNAL_ERROR500Unexpected server error
UPSTREAM_ERROR502Upstream API failure

Specs

List Specs

GET /api/specs

Returns all specs belonging to the authenticated user.

Create Spec

POST /api/specs
Content-Type: application/json

{
  "name": "My API",
  "version": "1.0.0",
  "sourceUrl": "https://example.com/openapi.json",
  "rawSpec": { ... }
}

Get Spec

GET /api/specs/:id

Update Spec

PUT /api/specs/:id
Content-Type: application/json

{
  "name": "Updated Name"
}

Delete Spec

DELETE /api/specs/:id

Servers

List Servers

GET /api/servers

Create Server (from Spec)

POST /api/specs/:specId/servers
Content-Type: application/json

{
  "slug": "my-api",
  "name": "My API Server",
  "authMode": "api_key",
  "baseUrl": "https://api.example.com/v1"
}

Get Server

GET /api/servers/:id

Update Server

PUT /api/servers/:id
Content-Type: application/json

{
  "name": "Updated Name",
  "rateLimitPerMinute": 120
}

Delete Server

DELETE /api/servers/:id

Tools

List Tools

GET /api/servers/:serverId/tools

Update Tool

PUT /api/servers/:serverId/tools/:toolId
Content-Type: application/json

{
  "isActive": false
}

Test Tool

POST /api/servers/:serverId/test
Content-Type: application/json

{
  "toolName": "listUsers",
  "input": { "limit": 10 }
}

Returns the tool execution result with timing information.

Credentials

Create Credential

POST /api/servers/:serverId/credentials
Content-Type: application/json

{
  "label": "Production API Key",
  "plaintextKey": "sk-...",
  "authType": "api_key"
}

The key is encrypted at rest and never returned in API responses.

Delete Credential

DELETE /api/servers/:serverId/credentials/:credentialId

Logs

List Logs

GET /api/servers/:serverId/logs?cursor=abc&limit=50

Returns cursor-paginated request logs. Supports optional query parameters: method, statusCode, from, to.

Usage

Get Usage Stats

GET /api/usage

Returns aggregate usage statistics for the authenticated user.

{
  "success": true,
  "data": {
    "serverCount": 3,
    "activeServers": 2,
    "requestsThisMonth": 1200
  }
}

Billing

Create Checkout Session

POST /api/billing/checkout
Content-Type: application/json

{
  "planId": "starter"
}

Creates a Stripe Checkout session for subscribing to a paid plan. planId must be "starter" or "pro".

Response:

{
  "success": true,
  "data": {
    "url": "https://checkout.stripe.com/c/pay/cs_..."
  }
}

Create Portal Session

POST /api/billing/portal

Creates a Stripe Billing Portal session for managing subscriptions, payment methods, and invoices. Returns 404 if the user has no billing account.

Response:

{
  "success": true,
  "data": {
    "url": "https://billing.stripe.com/p/session/..."
  }
}

Get Budget Cap

GET /api/billing/budget

Returns the user's configured overage spending cap. A null value means no cap is set.

{
  "success": true,
  "data": {
    "capEur": 10.00
  }
}

Set Budget Cap

POST /api/billing/budget
Content-Type: application/json

{
  "capEur": 10.00
}

Sets or removes the overage spending cap. Pass null to remove the cap. Value must be between 0 and 10,000 EUR.

Webhooks

Webhook endpoints use provider-specific signature verification (not Clerk Bearer tokens) and may return non-standard response payloads.

Stripe Webhook

POST /api/webhooks/stripe

Receives Stripe webhook events for subscription lifecycle management. Authenticated via stripe-signature header (not Bearer token). Returns { "received": true } on success.

Clerk Webhook

POST /api/webhooks/clerk

Receives Clerk webhook events for user lifecycle management. Authenticated via Clerk signature verification.