Skip to main content

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.