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

# Verify a Mobile Number (Server-Side Guide)

> Integrate Authmatech Verify from your backend: confirm a customer controls their mobile number silently, with the X-API-KEY and X-CLIENT-ID headers.

Authmatech Verify confirms that a customer controls the mobile number they present — silently, with no OTP. This guide covers the server-side integration: the request, the response, and the edge cases worth handling.

<Note>
  The encrypted code (`encryptedMobileNumber`) and `operatorId` are produced on the device by the Authmatech SDK after the [silent check](/concepts/silent-verification). This guide assumes your client has already obtained them and forwarded them to your backend. For the browser flow end to end, see [Web verification](/guides/web-verification).
</Note>

## The request

Call `POST /v1/api/verify` from your backend with both auth headers.

```bash theme={null}
curl -X POST "https://service.authmatech.com/v1/api/verify?maskMobile=false" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-CLIENT-ID: YOUR_CLIENT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "mobileNumber": "+962791234567",
    "encryptedMobileNumber": "BASE64_ENCRYPTED_BLOB_FROM_SDK",
    "operatorId": "ZAIN_JO",
    "serviceType": "LOGIN",
    "sdkSessionId": "b1f2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
  }'
```

### Body fields

<ParamField body="mobileNumber" type="string" required>
  The number the customer claims, in E.164 format (e.g. `+962791234567`).
</ParamField>

<ParamField body="encryptedMobileNumber" type="string" required>
  The encrypted identity code returned by the SDK. Authmatech validates this against `mobileNumber`.
</ParamField>

<ParamField body="operatorId" type="string">
  The mobile operator that confirmed the session (e.g. `ZAIN_JO`, `ORANGE_JO`). Optional but recommended.
</ParamField>

<ParamField body="serviceType" type="string">
  The use case driving the verification. One of `REGISTRATION`, `LOGIN`, `RESET_PASS`, `UPDATE_DETAILS`, or `TRANSACTION`. Used for analytics and risk context.
</ParamField>

<ParamField body="sdkSessionId" type="string">
  Optional. The session id returned by the SDK after [session registration](/sdks/mobile). When present, the verification is linked to the stored device context so [Shield](/guides/trust-shield-detect) and [Detect](/guides/trust-shield-detect) can reason about it.
</ParamField>

### Query parameter

<ParamField query="maskMobile" type="boolean" default="false">
  When `true`, the response includes a masked copy of the confirmed number (e.g. `********67`). This corresponds to the Verify N+ product and may be priced differently from a plain validity check.
</ParamField>

## The response

```json theme={null}
{
  "success": true,
  "messages": [
    { "type": "SUCCESS", "code": null, "message": null, "httpStatus": "OK" }
  ],
  "data": {
    "validNumber": true,
    "mobileNumber": "********67"
  }
}
```

<ResponseField name="data.validNumber" type="boolean">
  The verdict. `true` means the customer controls the number they presented.
</ResponseField>

<ResponseField name="data.mobileNumber" type="string">
  Present only when `maskMobile=true`. A masked copy of the confirmed number for display or audit.
</ResponseField>

<Warning>
  A `validNumber: false` is a **successful API call** (HTTP 200) with a negative verdict — not an error. Branch your application logic on `data.validNumber`, and reserve error handling for non-`200` responses and `success: false`.
</Warning>

## Recommended flow

<Steps>
  <Step title="Collect the code on the client">
    The SDK runs the silent check and registers a session, giving you `encryptedMobileNumber`, `operatorId`, and `sdkSessionId`.
  </Step>

  <Step title="Forward to your backend">
    Send those values plus the claimed `mobileNumber` to your own server over TLS. Never call Verify from the browser — the API key must stay server-side.
  </Step>

  <Step title="Verify and act">
    Call `POST /v1/api/verify`. On `validNumber: true`, continue the journey. On `false`, offer [Verify+](#verify-for-mistyped-numbers) or a secondary check — the not-matched journey is captured in [Stuck+](/guides/stuck-plus) for win-back.
  </Step>

  <Step title="Optionally score the action">
    Pass the same `sdkSessionId` to [Trust](/guides/trust-shield-detect) or [Shield](/guides/trust-shield-detect) to add a confidence score or risk decision.
  </Step>
</Steps>

## Verify+ for mistyped numbers

Customers fat-finger digits, miss a number, or invert a pair. With most flows, that's the end of the journey. **Authmatech Verify+** keeps them moving by returning a secure, privacy-preserving **identity hint** — a masked copy of the confirmed number — without ever revealing full information.

Verify+ is the same endpoint with `?maskMobile=true`:

```bash theme={null}
curl -X POST "https://service.authmatech.com/v1/api/verify?maskMobile=true" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-CLIENT-ID: YOUR_CLIENT_ID" \
  -H "Content-Type: application/json" \
  -d '{ "mobileNumber": "+962791234567", "encryptedMobileNumber": "…", "operatorId": "ZAIN_JO", "serviceType": "REGISTRATION" }'
```

```json theme={null}
{ "data": { "validNumber": true, "mobileNumber": "********67" } }
```

Show the masked ending (`********67`) so the customer can confirm or correct their entry — guiding them back on track without exposing the full number. Verify+ may be priced differently from a plain validity check; check your plan.

## Handling failure modes

| Situation                           | What you'll see                     | What to do                                                                                                |
| ----------------------------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Customer controls the number        | `200`, `validNumber: true`          | Continue                                                                                                  |
| Number doesn't match the code       | `200`, `validNumber: false`         | Offer Verify+ as a hint; the not-matched journey is captured in [Stuck+](/guides/stuck-plus) for win-back |
| No mobile data / Wi‑Fi only         | SDK can't complete the silent check | Fall back to manual entry or retry on mobile data                                                         |
| Missing/invalid credentials         | `401`                               | Check `X-API-KEY` and `X-CLIENT-ID`                                                                       |
| Product disabled or balance expired | `400` with a message                | Check plan/balance; see [Errors](/errors)                                                                 |

## Related

<CardGroup cols={2}>
  <Card title="API: Verify a number" icon="code" href="/api/overview">
    Full reference with an interactive playground.
  </Card>

  <Card title="Web verification" icon="qrcode" href="/guides/web-verification">
    The browser flow, end to end.
  </Card>
</CardGroup>
