> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Worked samples

> First-call walkthroughs over the operator identity surface: Number Verification (Silent Auth), SIM Swap, and Device Location round trips with sandbox key semantics, plus the error envelope for an operator-side rejection.

## Worked request and response samples

Copy a request body as written, substitute your own value, and compare the response envelope. Every sample pairs a plain E.164 number — Devotel Orbit forwards it as the CAMARA subject — against a `dv_test_sk_*` sandbox key, so no operator is contacted, no credits are deducted, and the response carries `meta.test_mode: true`. `X-Test-Mode: true` behaves the same way when the caller authenticates with a dashboard session instead of a server-to-server key.

**The three end to end loops.** Number Verification (Silent Auth) proves the SIM behind the asserted number is in the device that made the call, SIM Swap answers whether that SIM changed inside a look-back window, and Device Location answers whether the device is inside a claimed geofence without ever returning coordinates. Fails closed is the rule for each of them: anything that is not an explicit affirmative reads as a negative.

### 1. Number Verification (Silent Auth)

<Note>
  `POST /api/v1/numbers/network-apis/number-verification:verify`
</Note>

Pass `"phoneNumber"` (E.164) or its SHA-256 equivalent `"hashedPhoneNumber"` — exactly one. Add `accessToken` when your device already completed the three-legged operator flow; without it the call still runs, but server-context possession is only as strong as the operator deployment allows.

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://api.orbit.devotel.io/api/v1/numbers/network-apis/number-verification:verify" \
      -H "X-API-Key: dv_test_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "phoneNumber": "+14155552671"
    }'
    ```

    ```typescript Node.js theme={null}
    const res = await fetch(
      "https://api.orbit.devotel.io/api/v1/numbers/network-apis/number-verification:verify",
      {
        method: "POST",
        headers: {
          "X-API-Key": process.env.ORBIT_TEST_API_KEY!,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ phoneNumber: "+14155552671" }),
      },
    );
    console.log(await res.json());
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "devicePhoneNumberVerified": true
    },
    "meta": {
      "request_id": "req_nva_s1",
      "timestamp": "2026-09-09T12:00:00.000Z",
      "test_mode": true
    }
  }
  ```
</ResponseExample>

`devicePhoneNumberVerified: false` means not confirmed — treat it as no assertion, never as proof of absence.

### 2. SIM Swap check

<Note>
  `POST /api/v1/numbers/network-apis/sim-swap:check`
</Note>

`maxAge` is the look-back in hours (1..2400, default 240). A `swapped: true` inside the window is a strong account-takeover signal — step up before you accept the session.

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://api.orbit.devotel.io/api/v1/numbers/network-apis/sim-swap:check" \
      -H "X-API-Key: dv_test_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "phoneNumber": "+14155552671",
      "maxAge": 240
    }'
    ```

    ```typescript Node.js theme={null}
    const res = await fetch(
      "https://api.orbit.devotel.io/api/v1/numbers/network-apis/sim-swap:check",
      {
        method: "POST",
        headers: {
          "X-API-Key": process.env.ORBIT_TEST_API_KEY!,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ phoneNumber: "+14155552671", maxAge: 240 }),
      },
    );
    console.log(await res.json());
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "swapped": false
    },
    "meta": {
      "request_id": "req_ssc_s2",
      "timestamp": "2026-09-09T12:00:01.000Z",
      "test_mode": true
    }
  }
  ```
</ResponseExample>

For the precise timestamp when you want the raw fact instead of a boolean, `POST /sim-swap:retrieve-date` returns the operator's last SIM-change time under the same envelope.

### 3. Device Location verification

<Note>
  `POST /api/v1/numbers/network-apis/device-location:verify`
</Note>

Send a circle — centre (`latitude`, `longitude`) and `radius` in metres (2,000..200,000) — and the operator answers whether the device is inside it without revealing where it actually is. `verificationResult` is `TRUE`, `FALSE`, `PARTIAL` (coverage overlap, not a clean hit), or `UNKNOWN` (no fix inside `maxAge` seconds, 60..3600).

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://api.orbit.devotel.io/api/v1/numbers/network-apis/device-location:verify" \
      -H "X-API-Key: dv_test_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "phoneNumber": "+14155552671",
      "latitude": 37.7749,
      "longitude": -122.4194,
      "radius": 5000,
      "maxAge": 300
    }'
    ```

    ```typescript Node.js theme={null}
    const res = await fetch(
      "https://api.orbit.devotel.io/api/v1/numbers/network-apis/device-location:verify",
      {
        method: "POST",
        headers: {
          "X-API-Key": process.env.ORBIT_TEST_API_KEY!,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          phoneNumber: "+14155552671",
          latitude: 37.7749,
          longitude: -122.4194,
          radius: 5000,
          maxAge: 300,
        }),
      },
    );
    console.log(await res.json());
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "verificationResult": "TRUE"
    },
    "meta": {
      "request_id": "req_dlv_s3",
      "timestamp": "2026-09-09T12:00:02.000Z",
      "test_mode": true
    }
  }
  ```
</ResponseExample>

### Error envelope — operator-side rejection

An off-spec body (a non-E.164 number, an out-of-range `radius`) is rejected before any operator sees it, so the 422 with `VALIDATION_ERROR` costs you nothing and carries the offending field in `error.details.issues`. When the operator itself rejects the request (an unknown subscriber, an out-of-range window) the rejection is mapped to a caller-correctable 422 with the operator's own code preserved in `upstream_code`; when the operator cannot be reached at all, the call surfaces as a 502 `UPSTREAM_ERROR` rather than a false result. Sandbox keys never reach an operator, so you see this shape only with a live key.

```json 422 theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "status": 422,
    "message": "CAMARA: the subscriber is unknown to the operator",
    "details": {
      "upstream_code": "NOT_FOUND",
      "phoneNumber": "+1415555****"
    }
  },
  "meta": {
    "request_id": "req_err_s4",
    "timestamp": "2026-09-09T12:00:03.000Z"
  }
}
```

The `phoneNumber` in every error detail is masked — a rejection never echoes the full E.164 subject back.
