Skip to content

API reference

Rentals

Keep a number for 7, 30 or 90 days and receive every SMS sent to it — useful for accounts you'll need to verify again.

Periods
7, 30 or 90 days, charged up front. Optional auto-renew while your balance covers it; switch it on or off any time with Update a rental.
Cancelling
Full refund within 10 minutes of the start if no SMS has arrived; after that, cancelling ends the rental with no refund.
Inbox
Every SMS to the number, from any sender, with the code extracted when we're confident.

Simulator inventory carries demo: true — fictional numbers, simulated SMS. The web app labels it wherever prices or stock are shown.

The Rental object

A number you keep for 7, 30 or 90 days. Every SMS sent to it lands in the rental's inbox, from any service.

Attributes

  • idstring

    Unique identifier, prefixed rnt_.

  • statusstring

    active until ends_at, then expired; or cancelled.

  • phone_numberstring

    The number in E.164 format.

  • The number's country.

  • daysinteger

    Rental period in days.

    One of:73090

  • pricestring

    Amount charged for the period in US dollars, as a decimal string.

  • price_microsinteger

    Amount charged for the period in micro-dollars (1 USD = 1,000,000).

  • starts_attimestamp

    When the rental first started. It doesn't move on renewal, so ends_at − starts_at spans every period so far; the 10-minute refund window also counts from here.

  • ends_attimestamp

    End of the current period. Each renewal moves it one period later.

  • auto_renewboolean

    Renew for another period at ends_at if your balance covers it. Change it with Update a rental.

  • message_countinteger

    Messages received so far.

  • last_message_attimestamp· nullable

    When the latest SMS arrived.

  • can_cancelboolean

    Whether the rental can be cancelled now.

  • demoboolean

    true for simulator inventory: fictional numbers and simulated SMS.

Rental object · example
{
  "id": "rnt_2Wv9KcP4xR7mLq3TzB8n",
  "status": "active",
  "phone_number": "+13125550188",
  "country": {
    "iso2": "US",
    "name": "United States",
    "dial_code": "+1"
  },
  "days": 30,
  "price": "6.00",
  "price_micros": 6000000,
  "starts_at": "2026-10-06T14:10:00.000Z",
  "ends_at": "2026-11-05T14:10:00.000Z",
  "auto_renew": false,
  "message_count": 0,
  "last_message_at": null,
  "can_cancel": true,
  "demo": true
}

The Rental quote object

What renting a number in a country would cost you right now.

Attributes

  • The country.

  • daysinteger

    Rental period in days.

    One of:73090

  • pricestring

    Your price for the period in US dollars, as a decimal string.

  • price_microsinteger

    Your price for the period in micro-dollars (1 USD = 1,000,000).

  • availableboolean

    Whether a number can be rented there now.

  • demoboolean

    true when the rental would be simulator inventory.

Rental quote object · example
{
  "country": {
    "iso2": "US",
    "name": "United States",
    "dial_code": "+1"
  },
  "days": 30,
  "price": "6.00",
  "price_micros": 6000000,
  "available": true,
  "demo": true
}

Quote a rental

GET/v1/rentals/quote

Returns what renting a number in country for days would cost you now, including your discount.

Query parameters

  • countrystringRequired

    ISO2 country code.

  • daysintegerRequired

    Rental period: 7, 30 or 90.

    One of:73090

Returns

Returns a Rental quote object.

  • 200The rental quote.

Errors

Any endpoint can also return unauthorized, account_disabled, rate_limited and internal_error, and method_not_allowed when called with another method.

curl -G https://passcode.sh/api/v1/rentals/quote \
  -H "Authorization: Bearer $PASSCODE_API_KEY" \
  -d country=US \
  -d days=30
Response · 200
{
  "country": {
    "iso2": "US",
    "name": "United States",
    "dial_code": "+1"
  },
  "days": 30,
  "price": "6.00",
  "price_micros": 6000000,
  "available": true,
  "demo": true
}

Rent a number

POST/v1/rentals

Rents a number in country for days and charges the period up front. Every SMS to the number is stored in the rental's inbox and sent as a rental.message_received webhook.

Cancel within 10 minutes, before any SMS arrives, for a full refund. Send an Idempotency-Key so a retried request can never rent (and charge) twice. See Idempotency.

Headers

  • Idempotency-Keystring· optional

    A unique string (e.g. a UUID), up to 255 characters. Retrying the same request with the same key returns the original rental; a different request with it fails with idempotency_conflict.

Body · application/json

  • countrystringRequired

    ISO2 country code.

  • daysintegerRequired

    Rental period.

    One of:73090

  • auto_renewboolean· optional

    Renew automatically at the end of each period while your balance covers it.

    Defaults to false.

Returns

Returns a Rental object.

  • 201The new rental. Its URL is in the Location header.Location · Path of the rental, e.g. /api/v1/rentals/rnt_….
  • 200The Idempotency-Key was used before: the original rental in its current state, with Idempotent-Replayed: true. Nothing is charged.Idempotent-Replayed · Always true on a replay.Location · Path of the original rental.

Errors

Any endpoint can also return unauthorized, account_disabled, rate_limited and internal_error, and method_not_allowed when called with another method.

curl https://passcode.sh/api/v1/rentals \
  -H "Authorization: Bearer $PASSCODE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "country": "US",
    "days": 30
  }'
Response · 201
{
  "id": "rnt_2Wv9KcP4xR7mLq3TzB8n",
  "status": "active",
  "phone_number": "+13125550188",
  "country": {
    "iso2": "US",
    "name": "United States",
    "dial_code": "+1"
  },
  "days": 30,
  "price": "6.00",
  "price_micros": 6000000,
  "starts_at": "2026-10-06T14:10:00.000Z",
  "ends_at": "2026-11-05T14:10:00.000Z",
  "auto_renew": false,
  "message_count": 0,
  "last_message_at": null,
  "can_cancel": true,
  "demo": true
}

List rentals

GET/v1/rentals

Returns up to your 100 most recent rentals, newest first, settled first (expired periods end or renew before we respond).

Query parameters

  • statusstring· optional

    Only rentals in this status.

    One of:activeexpiredcancelled

Returns

  • 200Rentals.

Errors

Any endpoint can also return unauthorized, account_disabled, rate_limited and internal_error, and method_not_allowed when called with another method.

curl -G https://passcode.sh/api/v1/rentals \
  -H "Authorization: Bearer $PASSCODE_API_KEY" \
  -d status=active
Response · 200
{
  "data": [
    {
      "id": "rnt_2Wv9KcP4xR7mLq3TzB8n",
      "status": "active",
      "phone_number": "+13125550188",
      "country": {
        "iso2": "US",
        "name": "United States",
        "dial_code": "+1"
      },
      "days": 30,
      "price": "6.00",
      "price_micros": 6000000,
      "starts_at": "2026-10-06T14:10:00.000Z",
      "ends_at": "2026-11-05T14:10:00.000Z",
      "auto_renew": false,
      "message_count": 0,
      "last_message_at": null,
      "can_cancel": true,
      "demo": true
    }
  ]
}

Retrieve a rental

GET/v1/rentals/{id}

Returns the rental, settled first.

Path parameters

  • idstringRequired

    The rental id (rnt_…).

Returns

Returns a Rental object.

  • 200The rental.

Errors

Any endpoint can also return unauthorized, account_disabled, rate_limited and internal_error, and method_not_allowed when called with another method.

curl https://passcode.sh/api/v1/rentals/rnt_2Wv9KcP4xR7mLq3TzB8n \
  -H "Authorization: Bearer $PASSCODE_API_KEY"
Response · 200
{
  "id": "rnt_2Wv9KcP4xR7mLq3TzB8n",
  "status": "active",
  "phone_number": "+13125550188",
  "country": {
    "iso2": "US",
    "name": "United States",
    "dial_code": "+1"
  },
  "days": 30,
  "price": "6.00",
  "price_micros": 6000000,
  "starts_at": "2026-10-06T14:10:00.000Z",
  "ends_at": "2026-11-05T14:10:00.000Z",
  "auto_renew": false,
  "message_count": 0,
  "last_message_at": null,
  "can_cancel": true,
  "demo": true
}

Update a rental

POST/v1/rentals/{id}

Changes an active rental's auto_renew. Turn it off to let the rental end at ends_at while keeping the number until then; turn it on to renew for another period at ends_at, charged to your balance if it covers the price.

The rental is settled first, so a period that has already ended expires (or renews under the old setting) before the change. Changing an ended rental fails with invalid_state.

Path parameters

  • idstringRequired

    The rental id (rnt_…).

Body · application/json

  • auto_renewbooleanRequired

    true to renew at the end of each period, false to end at ends_at.

Returns

Returns a Rental object.

  • 200The updated rental.

Errors

Any endpoint can also return unauthorized, account_disabled, rate_limited and internal_error, and method_not_allowed when called with another method.

curl https://passcode.sh/api/v1/rentals/rnt_2Wv9KcP4xR7mLq3TzB8n \
  -H "Authorization: Bearer $PASSCODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "auto_renew": false
  }'
Response · 200
{
  "id": "rnt_2Wv9KcP4xR7mLq3TzB8n",
  "status": "active",
  "phone_number": "+13125550188",
  "country": {
    "iso2": "US",
    "name": "United States",
    "dial_code": "+1"
  },
  "days": 30,
  "price": "6.00",
  "price_micros": 6000000,
  "starts_at": "2026-10-06T14:10:00.000Z",
  "ends_at": "2026-11-05T14:10:00.000Z",
  "auto_renew": false,
  "message_count": 0,
  "last_message_at": null,
  "can_cancel": true,
  "demo": true
}

List rental messages

GET/v1/rentals/{id}/messages

Returns every SMS received on the rental's number, newest first, with any code we could extract.

Path parameters

  • idstringRequired

    The rental id (rnt_…).

Query parameters

  • limitinteger· optional

    How many messages, 1–500.

    Defaults to 200.

    Between 1 and 500.

Returns

  • 200Messages.

Errors

Any endpoint can also return unauthorized, account_disabled, rate_limited and internal_error, and method_not_allowed when called with another method.

curl https://passcode.sh/api/v1/rentals/rnt_2Wv9KcP4xR7mLq3TzB8n/messages \
  -H "Authorization: Bearer $PASSCODE_API_KEY"
Response · 200
{
  "data": [
    {
      "id": "msg_9Tb3QzL6mW1cR8vX2pKd",
      "from": "40404",
      "body": "Your Discord verification code is 615204. Don't share it with anyone.",
      "code": "615204",
      "received_at": "2026-10-07T09:31:44.000Z"
    }
  ]
}

Cancel a rental

POST/v1/rentals/{id}/cancel

Ends an active rental immediately and releases the number. The price is refunded in full when no SMS has arrived and the rental started less than 10 minutes ago; otherwise nothing is refunded. Cancelling twice returns the same result.

Path parameters

  • idstringRequired

    The rental id (rnt_…).

Body

No body. Send an empty POST.

Returns

  • 200The cancelled rental and the refund.
  • The rental, now cancelled.

  • refundedstring

    Amount returned to your balance in US dollars, as a decimal string.

  • refunded_microsinteger

    Amount returned to your balance in micro-dollars (1 USD = 1,000,000).

Errors

Any endpoint can also return unauthorized, account_disabled, rate_limited and internal_error, and method_not_allowed when called with another method.

curl -X POST https://passcode.sh/api/v1/rentals/rnt_2Wv9KcP4xR7mLq3TzB8n/cancel \
  -H "Authorization: Bearer $PASSCODE_API_KEY"
Response · 200
{
  "rental": {
    "id": "rnt_2Wv9KcP4xR7mLq3TzB8n",
    "status": "cancelled",
    "phone_number": "+13125550188",
    "country": {
      "iso2": "US",
      "name": "United States",
      "dial_code": "+1"
    },
    "days": 30,
    "price": "6.00",
    "price_micros": 6000000,
    "starts_at": "2026-10-06T14:10:00.000Z",
    "ends_at": "2026-11-05T14:10:00.000Z",
    "auto_renew": false,
    "message_count": 0,
    "last_message_at": null,
    "can_cancel": false,
    "demo": true
  },
  "refunded": "6.00",
  "refunded_micros": 6000000
}