Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.modelslab.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Headless Agent Flow allows an AI agent or automation script to go from zero to generating content in 5 API calls, with no browser interaction required. Card data never touches ModelsLab servers — agents tokenize cards directly with Stripe.
All responses include X-RateLimit-Remaining and X-RateLimit-Reset headers for rate-limit awareness.

Stripe Publishable Key

Agents fetch the Stripe publishable key via the API, then create PaymentMethods directly with Stripe. Card data never touches ModelsLab servers.
curl --request GET 'https://modelslab.com/api/agents/v1/billing/stripe-config' \
  --header 'Authorization: Bearer <agent_access_token>'
Returns { "publishable_key": "pk_live_...", "instructions": "..." }. Always use this endpoint to get the current key — it handles key rotation automatically.

The 5-Step Flow

1

Create Account

curl --request POST 'https://modelslab.com/api/agents/v1/auth/signup' \
  --header 'Content-Type: application/json' \
  --data '{
    "email": "agent@example.com",
    "password": "secret123",
    "name": "Agent Runner"
  }'
A verification email is sent automatically.
2

Verify Email (Headless)

Extract the verification_code from the verification email and verify without a browser.
curl --request POST 'https://modelslab.com/api/agents/v1/auth/verify-email' \
  --header 'Content-Type: application/json' \
  --data '{
    "verification_code": "<code-from-email>"
  }'
Returns access_token and api_key directly.
3

Create Payment Method via Stripe

Use the publishable key from Step 1 of the flow (fetched via GET /billing/stripe-config) to tokenize card details. Card data never touches ModelsLab servers.
curl --request POST 'https://api.stripe.com/v1/payment_methods' \
  --user '<publishable_key>:' \
  --data 'type=card' \
  --data 'card[number]=4242424242424242' \
  --data 'card[exp_month]=12' \
  --data 'card[exp_year]=2027' \
  --data 'card[cvc]=123'
Returns a payment_method_id (e.g., pm_1Xyz...). Use this ID with ModelsLab endpoints — never send raw card numbers to ModelsLab.
4

Fund Wallet or Subscribe

Use the payment_method_id from Step 3 to either fund the wallet or create a subscription.Option A — Fund wallet (pay-as-you-go):
curl --request POST 'https://modelslab.com/api/agents/v1/wallet/fund' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "amount": 25,
    "payment_method_id": "pm_1Xyz..."
  }'
Option B — Subscribe to a plan:
curl --request POST 'https://modelslab.com/api/agents/v1/subscriptions' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "plan_id": 10,
    "payment_method_id": "pm_1Xyz..."
  }'
Use GET /subscriptions/plans first to discover available plan IDs.
5

Generate Content with Existing APIs

Use the existing generation APIs (/api/v6, /api/v7, /api/v8) with the api_key returned in Step 2. See the Image Generation, Video API, and Speech & Audio docs for endpoint details.
curl --request POST 'https://modelslab.com/api/v6/images/text2img' \
  --header 'Content-Type: application/json' \
  --data '{
    "key": "<api_key>",
    "model_id": "flux",
    "prompt": "A futuristic cityscape at sunset",
    "width": 1024,
    "height": 1024
  }'

Flow Diagram

1. POST /auth/signup                    --> account created, verification email sent
2. POST /auth/verify-email              --> email verified, access_token + api_key returned
3. POST Stripe /v1/payment_methods      --> card tokenized (pm_xxx), card data stays with Stripe
4. POST /wallet/fund or /subscriptions  --> pay-as-you-go or subscription (headless, no redirect)
5. Use /api/v6, /api/v7, /api/v8        --> generate content with the api_key from step 2

Alternative: Human-Assisted Payment

If your agent does not have access to card details or the card requires 3D Secure, use the Human-Assisted flow instead. The agent creates a Stripe-hosted payment link and forwards it to a human:
curl --request POST 'https://modelslab.com/api/agents/v1/billing/payment-link' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Content-Type: application/json' \
  --data '{"purpose": "fund", "amount": 25}'
The human completes payment on Stripe Checkout, is redirected to ModelsLab’s success page with a session_id, and relays it to the agent. The agent then confirms:
# For wallet funding
curl --request POST 'https://modelslab.com/api/agents/v1/wallet/confirm-checkout' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Content-Type: application/json' \
  --data '{"session_id": "cs_live_..."}'

# For subscriptions
curl --request POST 'https://modelslab.com/api/agents/v1/subscriptions/confirm-checkout' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Content-Type: application/json' \
  --data '{"session_id": "cs_live_..."}'
See Billing & Wallet for full details on the three payment paths.

Handling Card Failures

When a card is declined, the API returns HTTP 402 with a structured error:
{
  "data": null,
  "error": {
    "code": "payment_declined",
    "message": "Your card was declined.",
    "details": {
      "decline_code": "insufficient_funds",
      "payment_intent_id": "pi_xxx"
    }
  }
}
If a card requires 3D Secure authentication, the API returns HTTP 202:
{
  "data": {
    "payment": {
      "status": "requires_action",
      "payment_intent_id": "pi_xxx",
      "client_secret": "pi_xxx_secret_yyy"
    },
    "message": "Additional authentication is required. Use modelslab.com/pricing to do payment for this transaction."
  }
}

Rate Limits

LimiterLimitApplies to
agent-auth20/min per IP+emailSignup, login, verify, forgot-password
agent-billing15/min per IP+userWallet fund, subscriptions, payment methods
agent-general120/min per IP+userAll other authenticated endpoints

Idempotency

All billing mutations support an Idempotency-Key header. If you retry a request with the same key, the cached response is returned with idempotency_replay: true instead of charging again.
curl --request POST 'https://modelslab.com/api/agents/v1/wallet/fund' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Idempotency-Key: fund-25-20260220-abc' \
  --header 'Content-Type: application/json' \
  --data '{"amount": 25, "payment_method_id": "pm_1Xyz..."}'
Use deterministic idempotency keys (e.g., fund-{amount}-{date}-{nonce}) to prevent duplicate charges on retries.