Skip to content

Developers

Developer API

Public contract for server jobs. Create a bearer token under API keys. Your app talks to GetVerifyCode. It never calls 5SIM, Stripe, or Cryptomus. Money is integer USD cents. Client-sent prices are ignored.

Base URL https://getverifycode.com/api/v1. Cookie sessions on /api are for the website only. Shop settings can pause this surface with public_api_off. Machine spec: /openapi.yaml. Create a key.

Authentication

Send the plaintext token on every private request. It is shown once when you create it. It expires in one year. Creating a new developer key replaces the previous one. Public catalog, health, and packages do not need a token. Send Accept: application/json on every call.

Header
Authorization: Bearer YOUR_API_KEY

Errors

Domain failures use this shape. Upstream payloads, keys, and internal hostnames are never included. Validation failures from form requests use Laravel's message and errors object instead.

Typed error
{
  "error": {
    "code": "insufficient_funds",
    "message": "Insufficient available balance."
  }
}
Paused surface
HTTP 503

{
  "error": {
    "code": "public_api_off",
    "message": "The public API is paused."
  }
}

Missing or invalid tokens return HTTP 401 with Unauthenticated. Another user's activation, top-up, or key returns HTTP 404.

Health

Liveness for the public v1 surface. No token. Still returns 503 when the public API flag is off.

GET/healthPublic
curl
curl -s -H 'Accept: application/json' 'https://getverifycode.com/api/v1/health'
200
{
  "status": "ok"
}

Catalog

Public. No token. Cached. Retail cents and live stock only. No wholesale. Sample prices below are examples. fresh=1 on offers busts the cache.

GET/catalog/servicesPublic
curl
curl -s -H 'Accept: application/json' 'https://getverifycode.com/api/v1/catalog/services'
200
{
  "services": [
    {
      "slug": "whatsapp",
      "name": "WhatsApp",
      "from_cents": 52,
      "in_stock": true,
      "stock": 12
    }
  ]
}
GET/catalog/services/{service}/countriesPublic

Optional query operator, default any. Country codes are ISO.

curl
curl -s -H 'Accept: application/json' 'https://getverifycode.com/api/v1/catalog/services/whatsapp/countries?operator=any'
200
{
  "service": "whatsapp",
  "countries": [
    {
      "iso": "US",
      "slug": "united-states",
      "name": "United States",
      "code": "US",
      "dial": "+1",
      "in_stock": true,
      "retail_cents": 52
    }
  ]
}
GET/catalog/services/{service}/offersPublic
curl
curl -s -H 'Accept: application/json' 'https://getverifycode.com/api/v1/catalog/services/whatsapp/offers'
200
{
  "service": "whatsapp",
  "offers": [
    {
      "service": "whatsapp",
      "operator": "any",
      "iso": "US",
      "slug": "united-states",
      "name": "United States",
      "code": "US",
      "retail_cents": 52,
      "in_stock": true,
      "stock": 8
    }
  ]
}
GET/catalog/quotePublic

Required query service and country. Optional operator, default any.

curl
curl -s -H 'Accept: application/json' 'https://getverifycode.com/api/v1/catalog/quote?service=whatsapp&country=US&operator=any'
200
{
  "service": "whatsapp",
  "country": "US",
  "operator": "any",
  "retail_cents": 52,
  "in_stock": true,
  "currency": "USD"
}

Account

Token required. Same wallet as the website. available_cents can be spent. held_cents are reserved for a live number.

GET/meBearer
curl
curl -s -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/me'
200
{
  "user": {
    "id": 1,
    "name": "Ada",
    "email": "[email protected]",
    "email_verified": true,
    "banned": false,
    "max_purchase_cents": null,
    "google": false,
    "referral_code": "ADA12",
    "totp_enabled": false,
    "wallet": {
      "available_cents": 1000,
      "held_cents": 0,
      "currency": "USD"
    }
  }
}

Wallet

GET/walletBearer
curl
curl -s -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/wallet'
200
{
  "available_cents": 1000,
  "held_cents": 0,
  "currency": "USD"
}
GET/wallet/ledgerBearer

Laravel pagination, 25 rows per page. Use ?page=2. Amounts are integer cents.

curl
curl -s -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/wallet/ledger'
200
{
  "data": [
    {
      "id": 10,
      "type": "top_up",
      "amount_cents": 500,
      "available_delta": 500,
      "held_delta": 0,
      "available_after": 1500,
      "held_after": 0,
      "reference_type": "top_up",
      "reference_id": 3,
      "created_at": "2026-09-18T12:00:00+00:00"
    }
  ],
  "current_page": 1,
  "per_page": 25,
  "total": 1
}
GET/wallet/packagesPublic

No token. Package cents come from shop settings. Processor flags tell you which checkout path is live.

curl
curl -s -H 'Accept: application/json' 'https://getverifycode.com/api/v1/wallet/packages'
200
{
  "packages_cents": [500, 1000, 2500, 5000, 10000],
  "currency": "USD",
  "min_cents": 500,
  "stripe_enabled": true,
  "crypto_enabled": true
}

Top-ups

Token required. Email must be verified. amount_cents must match a listed package. The response includes checkout_url. Credits land after the payment webhook, not when checkout opens. Card is Stripe. Crypto is Cryptomus. Repeat the same idempotency_key (8 to 80 characters) to avoid a double invoice.

POST/wallet/top-ups/stripeBearer
POST/wallet/top-ups/cryptomusBearer
Body
{
  "amount_cents": 500,
  "idempotency_key": "topup-2026-09-18-01"
}
curl
curl -s -X POST -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"amount_cents":500,"idempotency_key":"topup-2026-09-18-01"}' \
  'https://getverifycode.com/api/v1/wallet/top-ups/stripe'
201
{
  "top_up": {
    "id": 12,
    "provider": "stripe",
    "status": "pending",
    "amount_cents": 500,
    "credited_cents": null,
    "checkout_url": "https://checkout.stripe.com/c/pay/cs_test_..."
  }
}
GET/wallet/top-ups/{id}Bearer, owner
curl
curl -s -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/wallet/top-ups/12'

Top-up status is pending, paid, failed, or reversed.

Activations

Holds retail cents, then asks the provider for a number. Repeat the same idempotency key to avoid a double buy. A sent retail_cents field is ignored.

POST/activationsBearer
Body
{
  "service": "whatsapp",
  "country": "US",
  "operator": "any",
  "idempotency_key": "buy-2026-09-18-01"
}
curl
curl -s -X POST -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"service":"whatsapp","country":"US","operator":"any","idempotency_key":"buy-1"}' \
  'https://getverifycode.com/api/v1/activations'
201
{
  "activation": {
    "id": 88,
    "status": "pending",
    "service": "whatsapp",
    "country": "US",
    "operator": "any",
    "phone_number": "+12015550148",
    "retail_cents": 52,
    "currency": "USD",
    "expires_at": "2026-09-18T12:20:00+00:00",
    "completed_at": null,
    "sms": []
  }
}
GET/activations/{id}Bearer, owner

Poll about every 2.5 seconds while status is pending. When an SMS arrives, sms[].otp_code is the parsed code. Unused holds return if you cancel in time or if the 20 minute window ends with no SMS.

curl
curl -s -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/activations/88'
POST/activations/{id}/cancelBearer, owner
curl
curl -s -X POST -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' \
  'https://getverifycode.com/api/v1/activations/88/cancel'
GET/activationsBearer

Owner list. Latest 50 rows.

curl
curl -s -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/activations'
200
{
  "activations": [
    {
      "id": 88,
      "status": "received",
      "service": "whatsapp",
      "country": "US",
      "operator": "any",
      "phone_number": "+12015550148",
      "retail_cents": 52,
      "currency": "USD",
      "expires_at": "2026-09-18T12:20:00+00:00",
      "completed_at": "2026-09-18T12:04:12+00:00",
      "sms": [
        {
          "sender": "WhatsApp",
          "body": "Your code is 482193",
          "otp_code": "482193"
        }
      ]
    }
  ]
}

After purchase

  1. POST activations. Save the id and phone_number.
  2. Paste the number only where you are allowed to complete a check.
  3. GET activations/id until sms has otp_code, or until timeout.
  4. POST cancel if you do not want to wait. That releases the hold.

Status values

  • pending. Number is live. Wallet cents are held.
  • received. SMS stored. Hold captured.
  • canceled. You or support released the hold.
  • timeout. Window ended. Hold returned.
  • failed. Provider or price check refused the sale. Hold returned.
  • refunded. Admin force refund.

API keys

Token required. List returns metadata only. POST returns plaintext once and replaces any existing developer key. DELETE is owner only.

GET/api-keysBearer
curl
curl -s -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/api-keys'
200
{
  "keys": [
    {
      "id": 4,
      "name": "developer",
      "last_used_at": null,
      "expires_at": "2027-09-18T12:00:00+00:00",
      "created_at": "2026-09-18T12:00:00+00:00"
    }
  ]
}
POST/api-keysBearer
curl
curl -s -X POST -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/api-keys'
201
{
  "key": {
    "id": 5,
    "name": "developer",
    "last_used_at": null,
    "expires_at": "2027-09-18T12:00:00+00:00",
    "created_at": "2026-09-18T12:00:00+00:00"
  },
  "token": "5|plaintext-shown-once"
}
DELETE/api-keys/{id}Bearer, owner
curl
curl -s -X DELETE -H 'Accept: application/json' -H 'Authorization: Bearer YOUR_API_KEY' 'https://getverifycode.com/api/v1/api-keys/5'
200
{
  "ok": true
}

Limits

  • Catalog, health, and packages: 60 requests per minute.
  • Buy a number: 30 per hour per account.
  • Cancel: 20 per minute.
  • Create a key: 10 per minute. Revoke: 20 per minute.
  • Start a top-up: 10 per minute.
  • Number window is 20 minutes unless shop settings change it.

Error codes

  • insufficient_funds. Add credits first. HTTP 422.
  • wallet_frozen. Admin froze the wallet. HTTP 403.
  • banned. The account is suspended. HTTP 403.
  • max_purchase_exceeded. Raise or clear max purchase price.
  • negative_margin. That number is unavailable at a safe price.
  • provider_unavailable. Wholesale is paused or busy.
  • provider_error. The provider refused the request.
  • invalid_country. That country name is not in the catalog.
  • invalid_operator. That operator is not available.
  • not_cancellable. The number is no longer pending.
  • public_api_off. The v1 surface is paused. HTTP 503.

Email [email protected] with a token prefix, never the full secret.