# EviSMS

EviSMS is the Namirial Notify service for sending certified mobile communications through SMS and RCS. In the standard EviSMS flow, the certified content is the message itself — delivered directly to the recipient's device, with evidence recorded for processing, sending, delivery, and where supported, reading.

:::info EviSMS is a direct-message service
The certified content is the message itself, delivered straight to the recipient's device. If you need hosted content, recipient authentication before reading, or formal accept/reject interactions, use [EviNotice](/products/namirialnotify/services/evinotice) instead.
:::

For the API reference, see the [EviSMS API](/products/namirialnotify/apis/evisms-api).

## When to use EviSMS

Use EviSMS when:

- **You need certified delivery directly to a mobile device** — in the standard flow, the message arrives in the recipient's SMS inbox or RCS client without requiring them to follow a link or open a hosted page.
- **Speed and reach are priorities** — SMS reaches virtually any mobile number worldwide; RCS adds richer formatting and read receipts where the operator supports it.
- **The communication fits within mobile message constraints** — the certified content is the SMS or RCS message text itself.


Use [EviMail](/products/namirialnotify/services/evimail) when the certified communication is an email with attachments, HTML content, or commitment workflows. Use [EviNotice](/products/namirialnotify/services/evinotice) when you need controlled access to the content, recipient authentication before reading, or explicit acceptance/rejection workflows.

## How EviSMS works

### Lifecycle overview


```mermaid
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#E4F2F2', 'primaryBorderColor': '#006660', 'primaryTextColor': '#0A1111', 'lineColor': '#047C76', 'secondaryColor': '#CDDBDB', 'tertiaryColor': '#f5fafa', 'edgeLabelBackground': '#f5fafa', 'transitionColor': '#047C76'}}}%%
stateDiagram-v2
    [*] --> New : Submit accepted
    New --> Ready : Validated and certified
    Ready --> Dispatched : Queued for channel dispatch
    Dispatched --> Sent : Operator accepted message for routing
    Sent --> Delivered : Delivery confirmation received
    Delivered --> Read : Recipient opened message (RCS only)
    Delivered --> Closed : Lifecycle complete
    Read --> Closed : Lifecycle complete
    Sent --> Closed : TimeToLive elapsed
    Sent --> Failed : Recoverable delivery failure
    Failed --> Closed : Closed after failure
```

`State: Failed` is recoverable and does not make the communication final. Wait for `Closed` and inspect the final `Outcome`; permanent failure is represented by `Outcome: Failed`.

### Key state transitions

**New → Ready → Dispatched** — These three transitions happen in rapid succession within a single processing step. By the time the platform fires the first callback, the message is typically already at `Dispatched`. The `Ready` event occurs before `Dispatched`, but their callbacks are delivered and retried independently.

**Dispatched → Sent** — The SMS or RCS operator accepted the message for routing.

**Sent → Delivered** — A delivery confirmation was received from the operator. For SMS this is a delivery receipt; for RCS this is a delivery acknowledgement.

**Delivered → Read** — The recipient opened the message. **RCS only**, and only when the operator and recipient device support read receipts. This state is not reachable via SMS.

**Delivered / Read / TTL / terminal failure → Closed** — Plain SMS normally closes after delivery. RCS closes once the required delivery and read signals are available, or when the TTL elapses. A terminal failure also closes the lifecycle.

## Submit a certified message


```
POST /v1/EviSms/Submit
```

Returns `{ "eviId": "..." }` on success.

### Required fields

| Field | Description |
|  --- | --- |
| `Text` | The content of the SMS or RCS message. This is the certified content delivered to the recipient. |
| `Recipient.PhoneNumber` | The recipient's mobile number in E.164 format (e.g. `+34600000000`). |


### Useful fields you should configure

- **`LookupKey`** — your own correlation key, filterable in Query. No uniqueness enforced server-side.
- **`IssuerName`** — the legal name or short identifier of the sending organisation, recorded in the certification evidence. This is **not** the sender shown in the recipient's inbox — the inbox sender (the alphanumeric sender ID or number) is configured at the account level, separately from `IssuerName`.
- **`Recipient.LegalName`** — the legal name of the recipient, recorded in the certification evidence.


### Options

All delivery and certification configuration lives inside the `Options` object.

Every field in `Options` is optional at the API level. When you omit one, the platform applies a default — for example `Language` follows your site's configured language and `EvidenceAccessControlMethod` follows the account's configured default method. The web submission form pre-selects these same defaults, which is why they can look mandatory in the portal — but the API only requires the fields listed under [Required fields](#required-fields) above. The only conditional requirement is the challenge pair when `EvidenceAccessControlMethod` is `Challenge`.

- **`CertificationLevel`** — the legal framework applied. Supported values include `Standard`, `Advanced`, and regional variants such as `Standard_EU` or `Advanced_EU`. Available levels depend on your account subscription.
- **`DeliveryChannels`** — the channel or channels to use. Supported values: `SMS`, `RCS`. When both are specified, Namirial Notify attempts delivery in priority order. See [Delivery channels](#delivery-channels) below.
- **`TimeToLive`** — minutes the platform will attempt delivery before the message expires. Range: 60–86,400 (1 hour to 60 days).
- **`Language`** — language for any platform-generated notification text. Accepted values: `ca`, `de`, `en`, `es`, `fr`, `it`, `pt`, `pt-BR`, `ro`.
- **`AffidavitLanguage`** — language for generated affidavit PDFs. Accepts `el` (Greek) in addition to `Language` values.
- **`DeliveryAppearance`** — controls whether the delivered message uses the certified presentation or the plain `AsIs` appearance.
- **`EvidenceAccessControlMethod`** — controls how the recipient accesses the evidence record. Supported values: `Public`, `Challenge`, `AutoChallenge`. When omitted, the account's configured default method applies.
- **`OnlineRetentionPeriod`** — number of years the message and its evidence remain accessible online.


:::info EviSMS does not support commitment
EviSMS has no accept/reject (commitment) functionality. If you need acceptance or rejection workflows, use [EviNotice](/products/namirialnotify/services/evinotice) instead — it exposes this through a field named `CommitmentChoice`.
:::

### Callbacks

- **`PushNotificationUrl`** — HTTPS endpoint to receive state callbacks. Must be publicly reachable.
- **`PushNotificationFilter`** — state transitions that trigger a callback. Valid values: `Ready`, `Sent`, `Dispatched`, `Delivered`, `Read`, `Failed`, `Closed`, `AffidavitPublished`. `AffidavitPublished` is a platform meta-event that fires when affidavit generation completes — it is not a lifecycle state.
- **`PushNotificationExtraData`** — arbitrary string echoed back in every callback. Use it to embed a routing key or internal record ID.


### Idempotency

Include `X-Evi-IdempotencyToken` on every Submit. Use a UUID and keep it constant across retries. A replay of a previously `200 OK` submission returns `202 Accepted`; the message is not resubmitted.

## Delivery channels

`DeliveryChannels` accepts `SMS`, `RCS`, or both. When both are specified, the platform attempts delivery in the order listed.

| Channel | Delivery evidence | Read evidence | Fallback |
|  --- | --- | --- | --- |
| `SMS` | Operator delivery receipt | Not supported | — |
| `RCS` | Operator delivery acknowledgement | Supported where operator and device allow | Falls back to SMS when specified as second channel |


**Recommended pattern for maximum reach with read evidence:**


```json
"DeliveryChannels": ["RCS", "SMS"]
```

This attempts RCS first (with read receipt support) and falls back to SMS if RCS is unavailable. When the fallback fires, the state machine continues normally — `Sent`, `Delivered`, and `Closed` still apply regardless of which channel succeeded.

## Callbacks and what you receive

When a state in `PushNotificationFilter` is reached, Namirial Notify sends an HTTP POST to `PushNotificationUrl`.

### Base payload

| Field | Type | Description |
|  --- | --- | --- |
| `Identifier` | string | Unique ID of this callback delivery. Use it to deduplicate — the platform retries on non-2xx and on timeouts. |
| `Kind` | string | The state or event that triggered this callback (e.g. `Sent`, `Delivered`, `Read`, `Closed`, `AffidavitPublished`). |
| `Date` | datetime | Timestamp of the state transition. |
| `EvidenceId` | UUID | The `eviId` of the EviSMS, as returned at submission. |
| `EvidenceType` | string | Always `eviSMS` for EviSMS callbacks. |
| `EvidenceState` | string | Current state at the time the callback was sent. |
| `Owner` | string | Identifier of the account that submitted the message. |
| `OwnerEmail` | string | Email address of the submitting account. |
| `AdditionalData` | object | Event-specific fields. Always includes the fields listed below. |


### `AdditionalData` fields — always present

| Field | Description |
|  --- | --- |
| `Source` | The sender display name (the account-configured sender), not the submitted `IssuerName`. |
| `Destination` | Recipient phone number. |
| `LookupKey` | The integrator-assigned lookup key set at submission. |
| `State` | Current lifecycle state. |
| `CreationDate` | Timestamp when the message was submitted. |
| `ExtraData` | The `PushNotificationExtraData` value set at submission, if provided. |


### `AdditionalData` fields — per event

| Callback `Kind` | Extra fields |
|  --- | --- |
| `Closed` | `Outcome` — the final outcome of the message lifecycle. `OutcomeDescription` — human-readable description of the outcome. |
| `AffidavitPublished` | `AffidavitId` — unique ID of the generated affidavit. `AffidavitKind` — the kind generated. `AffidavitName` — filename of the affidavit PDF. |


### Callback reliability

Make your handler idempotent, keyed on `Identifier`. Return `2xx` promptly. Use `PushNotificationExtraData` to embed a routing key for correlation without a separate API call.

## States reference

| State | Description |
|  --- | --- |
| `Unknown` | State is not known or has not been mapped. |
| `Draft` | Message has been staged but not yet submitted. |
| `New` | Message has been accepted by the platform. |
| `Ready` | Message has been validated, certified, and queued for dispatch. Transitions to `Dispatched` immediately. |
| `Dispatched` | Message has been handed to the sending process and is ready for the operator. |
| `Sent` | The SMS or RCS operator accepted the message for routing. |
| `Delivered` | Delivery confirmation received from the operator. |
| `Read` | Recipient opened the message. **RCS only**, where the operator and device support read receipts. |
| `Closed` | Message lifecycle is complete. |
| `Failed` | A recoverable processing or delivery failure occurred. The platform may retry or advance to a later state. |


**On `Ready`:** this state is extremely transient — the platform moves from `Ready` to `Dispatched` in the same processing step. The `Ready` event occurs before `Dispatched`, but their callbacks are delivered and retried independently, so do not rely on callback arrival order.

**On `Read`:** only reachable via RCS. When the delivery channel is SMS, `Read` will never fire. Plan your callback handling to treat `Read` as optional enrichment rather than a required step.

## Evidence and affidavits

`AffidavitKinds` selects which evidence events generate signed affidavit PDFs. Generation is asynchronous; you receive an `AffidavitPublished` callback when each affidavit is ready.

### When each affidavit is generated

| `AffidavitKinds` value | Triggers at | Notes |
|  --- | --- | --- |
| `Submitted` | `Ready` | Certifies the message content at submission time. |
| `SubmittedAdvanced` | `Ready` | Advanced variant with extended content certification. |
| `TransmissionResult` | `Sent` | Certifies the outcome of the send attempt via the delivery channel. |
| `DeliveryResult` | `Delivered` | Certifies delivery confirmation from the operator. |
| `Read` | `Read` | Certifies that the recipient opened the message. RCS only. |
| `Closed` | `Closed` | Certifies the end of the message lifecycle. |
| `ClosedAdvanced` | `Closed` | Advanced variant of the closure affidavit. |
| `Complete` | `Closed` | Certifies the full chain from submission to closure. |
| `CompleteAdvanced` | `Closed` | Advanced variant of the complete lifecycle affidavit. |
| `Event` | Various technical events | Internal technical record for events without a more specific affidavit kind. |


## Querying status

Use the Query endpoint as a fallback when callbacks lag, for point-in-time snapshots, or for batch reconciliation.


```
GET /v1/EviSms/Query
```

If `Limit` is omitted, the API defaults to `100`. The default drops to `25` when affidavit metadata is included.

Common filters:

- `WithLookupKeys=your-key` — fetch by your correlation key.
- `OnState=Closed` — fetch only closed messages.
- `WithOutcome=Delivered` — fetch by final outcome.


## First-call walkthrough

### What you need

- Namirial Notify credentials (username and password)
- A recipient mobile number for testing
- An HTTPS endpoint to receive callbacks (or use a tool like [Webhook.site](https://webhook.site) for initial testing)


### Step 1 — Submit your first message


```http
POST /v1/EviSms/Submit
Authorization: Basic <base64(username:password)>
Content-Type: application/json
X-Evi-IdempotencyToken: <uuid>

{
  "Text": "This is a test certified SMS message.",
  "LookupKey": "test-001",
  "IssuerName": "TestCo",
  "Recipient": {
    "PhoneNumber": "+34600000000"
  },
  "Options": {
    "CertificationLevel": "Standard_EU",
    "DeliveryChannels": ["SMS"],
    "AffidavitKinds": ["Submitted", "DeliveryResult", "Closed"],
    "PushNotificationUrl": "https://your-endpoint.example.com/callbacks",
    "PushNotificationFilter": ["Sent", "Delivered", "Closed", "AffidavitPublished"]
  }
}
```

A `200 OK` response contains `{ "eviId": "..." }`. Store the `eviId`.

### Step 2 — Verify the message progresses


```http
GET /v1/EviSms/Query?WithLookupKeys=test-001
Authorization: Basic <base64(username:password)>
```

Confirm the message moves through `New` → `Ready` → `Dispatched` → `Sent`.

### Step 3 — Confirm delivery

Confirm that a `Sent` callback fires and that `SentOn` is populated in the Query response. If the operator provides a delivery signal, also verify the `Delivered` callback and `DeliveredOn`. If you requested a delivery affidavit, verify that the `DeliveryResult` affidavit appears through an `AffidavitPublished` callback; the affidavit kind alone is not proof of successful delivery.

### Step 4 — Test the failure path

Submit a message to a well-formed number that is known to return a permanent delivery failure. Confirm the test number with your Namirial Notify contact so the result is deterministic. Verify that:

- The message reaches `Failed` then `Closed` with `Outcome: Failed`
- A `Failed` callback fires to your endpoint


## Integration checklist

- Set `LookupKey` on every Submit and persist `eviId` from the response.
- Send `X-Evi-IdempotencyToken` (UUIDv4) on every Submit. Treat `202 Accepted` as success.
- Set `IssuerName` to the issuer's legal name or identifier for the evidence record. It does not control the sender shown in the recipient's inbox.
- When using `["RCS", "SMS"]` as `DeliveryChannels`, handle callbacks for both channels — the `Sent` and `Delivered` callbacks fire regardless of which channel succeeded.
- Do not rely on `Ready` callbacks for business logic — the state is transient and `Dispatched` follows immediately.
- Subscribe to `Read` only if you specifically need read receipt evidence and are using RCS — it will never fire for SMS-only deliveries.
- Include `AffidavitPublished` in `PushNotificationFilter` if you download affidavits programmatically.
- Make your callback handler idempotent, keyed on `Identifier`.
- Use Query as a fallback when callbacks lag.


## Troubleshooting

| Symptom | Likely causes | What to check | What to do |
|  --- | --- | --- | --- |
| No callbacks received | `PushNotificationUrl` missing or unreachable; `PushNotificationFilter` omits the `Kind` you expect; endpoint returned non-2xx and retries exhausted | Query state directly; server access logs for the callback `Identifier` | Confirm URL and filter; use Query polling as fallback |
| Message stays in `Dispatched` or `Sent` | Operator processing delay; recipient device off or unreachable | `SentOn`, `DeliveredOn` timestamps in Query | Wait; do not resubmit |
| Recipient did not receive the SMS | Wrong number; operator routing issue; spam filter on device | `Delivered` callback and `DeliveredOn` timestamp | Confirm the number is valid E.164; retry with a new idempotency token |
| `Read` callback never fires | Delivery channel is SMS (not RCS); recipient device does not support RCS read receipts; operator does not pass read events | `DeliveryChannels` in your submit request | Expected behaviour for SMS — treat `Read` as optional enrichment |
| Message closed with `Outcome: Failed` | A processing or transmission failure was recorded before closure | `FailedOn`, callback payloads, and failure details | Correct the number or configuration; resubmit with a new idempotency token only after the cause is fixed |
| Affidavit not available | Generation is asynchronous; `AffidavitPublished` has not fired yet; the kind was not included in `AffidavitKinds` at submission | Query with `IncludeAffidavits=true` | Wait for `AffidavitPublished`; if kind is missing it cannot be added retroactively — resubmit |
| Submit → `400 Bad Request` | Missing `Text` or `Recipient.PhoneNumber`; invalid `CertificationLevel`; other field-level validation failure | `responseStatus.errors[]` for field-level details | Fix the flagged field; retry with a new idempotency token |
| Submit → `401 Unauthorized` | Wrong environment base URL; credentials rotated | `Authorization` header; confirm target environment | Re-issue credentials |
| Submit → `403 Forbidden` | Account not provisioned for EviSMS | Account permissions | Contact your Namirial Notify account manager |


## Related

- [EviSMS API](/products/namirialnotify/apis/evisms-api)
- [How to create a new EviSMS](/products/namirialnotify/issuer/create-evisms)
- [EviMail](/products/namirialnotify/services/evimail)
- [EviNotice](/products/namirialnotify/services/evinotice)
- [API documentation](/products/namirialnotify/dev/api-documentation)
- [Callbacks and webhooks](/products/namirialnotify/dev/callbacks)
- [Security and authentication](/products/namirialnotify/dev/security-best-practices)
- [States and outcomes](/products/namirialnotify/user-guides/states-outcomes)
- [Evidence and affidavits](/products/namirialnotify/user-guides/evidences-affidavits)