> For the complete documentation index, see [llms.txt](https://docs.sms4sats.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sms4sats.com/api-reference/catalog-and-quotes.md).

# Catalog & Quotes

Discover service codes and request current quotes before creating an order.

Catalog requests are read-only. Quote requests check live inventory and pricing but do not issue invoices or reserve a number.

## Receive-SMS countries

<mark style="color:blue;">`GET`</mark> `/v2/receive-sms/countries`

Use this public endpoint to populate a receive-SMS country picker. No authentication, order token, or query parameters are required. It reads bundled country metadata only: no database/provider requests, invoices, reservations, or payments.

```bash
curl -sS 'https://api.sms4sats.com/v2/receive-sms/countries'
```

Response shape (the real response includes the complete country list):

```json
{
  "type": "receive-sms",
  "defaultCountry": "auto",
  "legacyCountryAliases": { "999": "auto" },
  "countries": [
    { "id": "auto", "name": "Auto-select" },
    { "id": "74", "name": "Afghanistan" }
  ]
}
```

* Use `countries[].name` as the display label and pass `countries[].id` as the string `country` value to catalog, quote, and create-order requests.
* Auto-select is first; the remaining countries are sorted by English name. IDs are stable SMS4Sats country identifiers, **not telephone calling codes or ISO numeric codes**.
* `defaultCountry: "auto"` means the server selects a country when quoting an order. A quote or order response may therefore contain a concrete country ID instead of `"auto"`.
* **Legacy migration:** normalize saved country `999` (number or string) to `"auto"` before calling v2. `legacyCountryAliases` describes this client-side conversion; it does not change existing endpoints to accept `999` as an Auto alias. All other picker IDs remain unchanged.
* This is metadata, not a live inventory list. A listed country/service combination may be unavailable. Request a quote and handle `409 UNAVAILABLE`; do not infer availability from the picker.

```js
const country = picker.legacyCountryAliases[String(savedCountry)]
  ?? String(savedCountry);
```

## Receive-SMS catalog

<mark style="color:blue;">`GET`</mark> `/v2/receive-sms/catalog?country={country}`

`country` accepts `auto`, a supported numeric country ID, ISO alpha-2 code, or country name. It defaults to `auto`.

```bash
curl -sS 'https://api.sms4sats.com/v2/receive-sms/catalog?country=auto'
```

```json
{
  "type": "receive-sms",
  "country": "auto",
  "services": [
    { "code": "tg", "name": "Telegram" },
    { "code": "go", "name": "Google,youtube,Gmail" }
  ],
  "updatedAt": "2026-09-30T19:00:00.000Z"
}
```

The catalog lists supported service metadata, not guaranteed inventory. Use `services[].code` as `service`, then request a quote.

## Quote a receive-SMS order

<mark style="color:green;">`POST`</mark> `/v2/receive-sms/quote`

| Body field        | Type   | Required | Description                                      |
| ----------------- | ------ | -------- | ------------------------------------------------ |
| `country`         | string | Yes      | `auto`, numeric ID, ISO code, or country name    |
| `service`         | string | Yes      | Catalog code or recognized service name          |
| `referral`        | string | No       | Referral metadata, maximum 320 characters        |
| `clientRequestId` | string | No       | Client correlation value, maximum 200 characters |

```bash
curl -sS -X POST https://api.sms4sats.com/v2/receive-sms/quote \
  -H 'Content-Type: application/json' \
  -d '{"country":"auto","service":"tg"}'
```

```json
{
  "type": "receive-sms",
  "country": "151",
  "service": "tg",
  "durationMinutes": null,
  "availability": 120,
  "priceSats": 350
}
```

`country` may differ from the request when `auto` selects a country. Quotes may be up to five minutes old and do not guarantee availability. Always use the creation response's `priceSats` for payment UI.

## Rental catalog

<mark style="color:blue;">`GET`</mark> `/v2/rent-numbers/catalog?service={service}&durationMinutes={minutes}`

* `service` defaults to `full`.
* `durationMinutes` is normalized upward to a whole hour with a minimum of 120 and a maximum request value of 43,200.

```json
{
  "type": "rent-number",
  "service": "full",
  "durationMinutes": 120,
  "countries": [
    {
      "country": "1",
      "availability": 3,
      "durationMinutes": 120,
      "priceSats": 1800
    }
  ],
  "updatedAt": "2026-09-30T19:00:00.000Z"
}
```

An empty `countries` array means no matching rental is currently available.

## Quote a rental

<mark style="color:green;">`POST`</mark> `/v2/rent-numbers/quote`

```bash
curl -sS -X POST https://api.sms4sats.com/v2/rent-numbers/quote \
  -H 'Content-Type: application/json' \
  -d '{"country":"1","service":"full","durationMinutes":120}'
```

The response has the same fields as a receive-SMS quote, with `type: "rent-number"` and a normalized `durationMinutes`.

{% hint style="info" %}
Availability is inherently volatile. Handle `409 UNAVAILABLE` even when a quote succeeded moments earlier.
{% endhint %}
