ostra Create an account

Your tests read the codes your service sends.

Point any client at a line’s proxy port. When your own service texts the line, your test suite or your agent reads the code through the REST API, a webhook or the MCP server. For services you own or are authorized to test, under one account and the same rules.

Every account gets the REST API, webhooks, the sandbox, the MCP server and the command line tool.

Request

GET /v1/lines/LAX-V-22/messages/wait?timeout=60
Authorization: Bearer $OSTRA_KEY

Response, when the text lands

200
{
  "sender": "+12135550160",
  "code": "482915",
  "received_at": "2026-10-12T14:02:11Z"
}
Waiting up to 60 seconds for the next text on LAX-V-22. An example, shortened: the API reference lists every field.

Proxy ports, for any client

Every line has an HTTPS proxy port that takes its username and secret from anywhere. Pass it to your client’s proxy setting; four samples below.

curl

curl -x "https://$OSTRA_USER:$OSTRA_SECRET@lax.gw.ostranetwork.com:30022" \
  https://example.com/

Python

import os, requests

line = f"https://{os.environ['OSTRA_USER']}:{os.environ['OSTRA_SECRET']}@lax.gw.ostranetwork.com:30022"
r = requests.get("https://example.com/", proxies={"https": line})

Node

import { ProxyAgent, fetch } from 'undici'

const auth = Buffer.from(`${process.env.OSTRA_USER}:${process.env.OSTRA_SECRET}`).toString('base64')
const line = new ProxyAgent({ uri: 'https://lax.gw.ostranetwork.com:30022', token: `Basic ${auth}` })
const res = await fetch('https://example.com/', { dispatcher: line })

Playwright

const browser = await chromium.launch({
  proxy: {
    server: 'https://lax.gw.ostranetwork.com:30022',
    username: process.env.OSTRA_USER,
    password: process.env.OSTRA_SECRET,
  },
})

SOCKS5 and plain HTTP ports answer only the source addresses you list, with no credential. Ports by line ID

REST API

https://api.ostranetwork.com/v1, with a bearer key. The API uses your lines; it never creates them. Ostra assigns lines after verification.

CallDoes
GET /linesYour lines with their status, carrier and addresses
GET /lines/{id}One line: its number, proxy endpoints, addresses and health
POST /lines/{id}/new-carrier-ipAsk the carrier for a new address on this line; returns a job to follow
GET /lines/{id}/messagesTexts that arrived, with the codes Ostra read
GET /lines/{id}/messages/waitWait for the next text, up to 90 seconds
GET /lines/{id}/callsCalls that came in, with any code the caller keyed
GET /usageBytes and connections per line per day
POST /ordersOrder lines, on one carrier’s network or any. A line that is ready is assigned at once; otherwise the order waits for a line to be provisioned
POST /webhooksRegister an endpoint and the events it wants
Too soon
A new carrier IP asked for too soon is refused at once with 429 and next_allowed_at, and nothing is held to run later. At most once every 5 minutes and 24 times in any 24 hours per line, and not for an hour after one that left the line much slower.
Never on a schedule
No schedule changes a line’s address. A new carrier IP happens when you ask, or when Ostra’s recovery asks after the line loses IPv4 or IPv6; both count toward the line’s limit, and each is reported as line.ip_changed.

Webhooks

Ostra posts to your endpoint as things happen. Each delivery is signed with a timestamp and an HMAC made with that endpoint’s secret, and a failed one is retried with backoff for 24 hours. The dashboard has a button that sends a test event.

  • message.receivedA text arrived, with the code Ostra read from it
  • call.receivedA call came in and ended, with whether it had a code
  • line.ip_changedA line has a new carrier IP
  • line.downA line stopped carrying traffic and its port closed
  • line.upIt is carrying traffic again
  • line.renewal_upcomingA line’s monthly subscription renews soon

MCP server, for agents

A remote MCP server at mcp.ostranetwork.com gives an AI agent your lines, their texts, calls and codes, and a new carrier IP, with an API key or an Ostra sign-in, under the same rules as the API. It does not order lines, manage webhooks or read usage. Its tools are for testing services you own or are authorized to test.

ToolDoes
list_linesYour lines and their status
get_lineA line’s proxy endpoints and address, so the agent can point its browser at it
wait_for_codeWaits for the next code on a line, up to 90 seconds (60 by default). With none by then, it says so and returns where to wait from next
new_carrier_ipAsk for a new carrier IP; returns a handle at once, never a wait
get_new_carrier_ipFollow that handle until the new address is read
list_messagesRecent texts on a line
list_callsRecent calls on a line

Not included, on purpose

Creating lines or buying numbers. Texting or calling from a line. Solving CAPTCHAs, changing a browser’s fingerprint, or creating accounts. The limits on what a line may be used for are enforced on Ostra’s side, not left to a tool’s description. Acceptable use

Keys and sign-in

API keys
Made in the dashboard by an admin of your account, optionally limited to some lines and to reading only. Shown once; Ostra keeps only a hash. Revoking one stops it at once. Until your account is verified, a key reaches only the sandbox.
Apps and agents
An MCP client uses an API key, or signs in with your Ostra account: it opens Ostra’s sign-in in your browser, shows what it asks for in plain words, and you choose the account it may reach. Only clients Ostra has registered can sign in this way, and a sign-in made for the MCP server works only there.
The sandbox
LAX-SANDBOX-00, a simulator, answers the API with sample data and no phone behind it, so you can build before a line is yours. The sandbox