# EviSMS API

The EviSMS API lets you submit certified SMS and RCS messages and query the status of previously submitted messages. It is a REST API that uses HTTP Basic authentication and returns JSON responses.

## Environments

| Environment | Base URL |
|  --- | --- |
| Production | `https://api.evicertia.com` |
| Pre-production / QA | `https://api.ecertia.com` |


For the public Namirial Notify API environments, this V1 service is exposed under the `/v1` base path. Use public routes such as `/v1/EviSms/Submit` and `/v1/EviSms/Query`.

Some lower-level technical artifacts may show these V1 routes without the `/v1` prefix. For customer integrations, use the public `/v1` base path shown in this documentation.

For shared environment guidance across services, see [API documentation](/products/namirialnotify/dev/api-documentation#environments).

## Authentication

All endpoints require **HTTP Basic authentication**. Pass your Namirial Notify credentials as the username and password in the `Authorization` header.


```
Authorization: Basic <base64(username:password)>
```

For credential handling, callback hardening, and production security checks, see [Security and authentication](/products/namirialnotify/dev/security-best-practices).

## Idempotency

EviSMS Submit supports idempotent submission. Include the `X-Evi-IdempotencyToken` header with a unique value per logical operation (a UUID is recommended).

If the same token is submitted again after the original request completed with `200 OK`, the server returns `202 Accepted` with the original response body — the message is **not** resubmitted.

The following response codes are **not** cached and will re-execute the request regardless of token: `400`, `401`, `408`, `409`, `429`, and `5xx` responses.

## Error responses

EviSMS v1 uses a `responseStatus` object for error responses.


```json
{
  "responseStatus": {
    "errorCode": "ArgumentException",
    "message": "Text is required and cannot be empty.",
    "errors": [
      {
        "errorCode": "NotEmpty",
        "fieldName": "Text",
        "message": "Text is required and cannot be empty."
      }
    ]
  }
}
```

| Field | Description |
|  --- | --- |
| `errorCode` | Machine-readable error classifier |
| `message` | Human-readable summary of the error |
| `errors` | Array of field-level validation errors (present on `400` responses) |


Common status codes and their causes:

| Status | Typical cause |
|  --- | --- |
| `400 Bad Request` | Missing required field, invalid phone number format, or invalid field value |
| `401 Unauthorized` | Incorrect credentials or missing `Authorization` header |
| `403 Forbidden` | Account not provisioned for EviSMS |


For shared error handling guidance, see [Error handling](/products/namirialnotify/dev/error-handling).

## Endpoints

### Submit a certified SMS


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

Submits a new certified SMS or RCS message. On success, returns an `eviId` that uniquely identifies the submitted message and can be used to query its status later.

**Required fields:** `Text`, `Recipient` (with `PhoneNumber`).

Optional fields include `IssuerName`, `LookupKey`, and `Options`. All fields within `Options` — including `CertificationLevel`, `DeliveryChannels`, and `TimeToLive` — are optional. `Recipient.LegalName` is also optional.

| Response | Description |
|  --- | --- |
| `200 OK` | Message accepted. Body contains `{ "eviId": "..." }`. |
| `202 Accepted` | Returned when an idempotent replay matches a previously `200 OK` submission. The original response body is returned unchanged. See [Idempotency](#idempotency) above. |
| `400 Bad Request` | Invalid request. The OpenAPI specification defines a `responseStatus` object with `errorCode`, `message`, and optional `errors`. |
| `401 Unauthorized` | Authentication failed. |
| `403 Forbidden` | The authenticated account lacks the required API permission for EviSMS. |


**Example request:**


```json
POST /v1/EviSms/Submit HTTP/1.1
Authorization: Basic <base64(username:password)>
Content-Type: application/json
X-Evi-IdempotencyToken: 550e8400-e29b-41d4-a716-446655440001

{
  "LookupKey": "NOTIFICATION-67890",
  "Text": "You have a pending certified notification. Please confirm receipt.",
  "IssuerName": "Acme Corp",
  "Recipient": {
    "LegalName": "Alice Martin",
    "PhoneNumber": "+34612345678"
  },
  "Options": {
    "CertificationLevel": "Advanced_EU",
    "TimeToLive": 1440,
    "DeliveryChannels": ["SMS"],
    "PushNotificationUrl": "https://your-endpoint.example.com/callbacks/evisms",
    "PushNotificationFilter": ["Delivered", "Closed", "AffidavitPublished"],
    "AffidavitKinds": ["Submitted", "TransmissionResult", "DeliveryResult", "Closed"]
  }
}
```

**Example response (`200 OK`):**


```json
{
  "eviId": "87ffa214-e773-4bd5-9b8d-a8ef00fd80f8"
}
```

### Query certified SMS messages


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

Returns a list of certified SMS messages matching the specified filters. Results are paginated using `Limit` and `Offset`.

**Query parameters:**

| Parameter | Type | Description |
|  --- | --- | --- |
| `WithUniqueIds` | string | Filter by one or more unique IDs (comma-separated). |
| `WithLookupKeys` | string | Filter by one or more lookup keys (comma-separated). |
| `WithLinkedId` | string (UUID) | Filter by linked ID. |
| `OnState` | string | Filter by current state. |
| `WithOutcome` | string | Filter by outcome. |
| `OrderResultsBy` | string | Sort field for results. Supported value: `CreationDate`. |
| `Limit` | integer | Maximum number of results to return. |
| `Offset` | integer | Number of results to skip. |
| `IncludeAffidavits` | boolean | Include affidavit metadata in results. |


| Response | Description |
|  --- | --- |
| `200 OK` | Returns `{ "totalMatches": N, "results": [...] }`. |
| `401 Unauthorized` | Authentication failed. |


If `Limit` is omitted, the API uses a default of `100`. The default becomes `25` when the request includes affidavit metadata.

## Batch operations

Batch operations let you send the same certified SMS to many recipients as a single managed job.

:::note Base path
The batch endpoints are part of the **v2** API and live under the `/v2/EviSms/Batches` base path — not under the `/v1` base path used by the rest of the EviSMS API.
:::

The typical workflow is:

1. **Create** an empty batch with a `Description` — you receive a `BatchId`.
2. **Configure** the message and options (`PATCH .../{BatchId}`) — the SMS `Text`, certification level, callbacks, scheduling, and so on. EviSMS has no separate body or attachment endpoints; the message content is the `Text` field.
3. **Add recipients** (`POST .../Recipients`) — uploaded as a `text/csv` file.
4. **Start processing** by setting the batch `State` (via `PATCH`) once the batch is ready.


Poll `GET .../{BatchId}` to follow progress (`SentCount`, `FailedCount`, `ProgressPercentage`). Batch lifecycle states are `Draft`, `Submitted`, `Scheduled`, `Processing`, `Processed`, `Invalid`, and `Failed`.

:::note HTTP QUERY method
The two list endpoints (**Query batches** and **Query batch recipients**) are implemented with the HTTP `QUERY` method and accept their filters in a JSON request body. Because OpenAPI cannot express the `QUERY` method, they are documented as `GET` with the filter fields shown as query parameters. In practice, send the request with the HTTP `QUERY` verb and the fields in a JSON body.
:::

### Create an SMS batch


```
POST /v2/EviSms/Batches
```

Creates a new, empty batch. Only `Description` is required; the message text, recipients, and options are set with the subsequent batch endpoints.

| Field | Type | Description |
|  --- | --- | --- |
| `Description` | string | Required. Human-readable batch description (max 255 chars). |


| Response | Description |
|  --- | --- |
| `200 OK` | Returns `{ "BatchId": "<uuid>" }`. |
| `401 Unauthorized` | Authentication failed. |


### Query SMS batches


```
QUERY /v2/EviSms/Batches
```

Lists SMS batches owned by the caller (or the caller's site), with cursor pagination. Filters are sent in a JSON request body: `States` (array), `Cursor`, `Limit` (required, 1–100), `SortBy` (`LastUpdated`/`ScheduledFor`/`StartedOn`), `SortOrder` (`Ascending`/`Descending`), `Direction` (`Forward`/`Backward`), `TextSearch`.

| Response | Description |
|  --- | --- |
| `200 OK` | Returns `{ "Cursor": "...", "HasMoreResults": bool, "Results": [...] }`. |
| `400 Bad Request` | Malformed request. |
| `401 Unauthorized` | Authentication failed. |


### Get an SMS batch


```
GET /v2/EviSms/Batches/{BatchId}
```

Retrieves the full state of a batch, including its configured message template (nested `EviSms`) and processing progress.

| Response | Description |
|  --- | --- |
| `200 OK` | Returns the full batch object. |
| `400 Bad Request` | `BatchId` is missing or a default (empty) UUID. |
| `401 Unauthorized` | Authentication failed. |
| `404 Not Found` | No batch with the given `BatchId` was found. |


### Update an SMS batch


```
PATCH /v2/EviSms/Batches/{BatchId}
```

Updates batch metadata and the message template options, including the SMS `Text`. All fields are optional; only the fields supplied are changed. Setting `State` transitions the batch; setting `ScheduledDate` schedules it.

**Request body (all fields optional):** `IssuerName`, `ScheduledDate`, `State`, `Description`, `Text`, `TimeToLive`, `CostCentre`, `CertificationLevel`, `AffidavitKinds`, `Language`, `AffidavitLanguage`, `OnlineRetentionPeriod`, `LtaStorage`, `PushNotificationUrl`, `PushNotificationFilter`, `PushNotificationExtraData`, `DeliveryAppearance`, `BatchPushNotificationUrl`, `OwnerNotificationTemplate`.

| Response | Description |
|  --- | --- |
| `200 OK` | Batch updated. |
| `400 Bad Request` | Invalid request. |
| `401 Unauthorized` | Authentication failed. |
| `404 Not Found` | No batch with the given `BatchId` was found. |


### Delete an SMS batch


```
DELETE /v2/EviSms/Batches/{BatchId}
```

| Response | Description |
|  --- | --- |
| `204 No Content` | Batch deleted. |
| `401 Unauthorized` | Authentication failed. |
| `404 Not Found` | No batch with the given `BatchId` was found. |


### Add batch recipients


```
POST /v2/EviSms/Batches/{BatchId}/Recipients
```

Adds recipients by uploading a `text/csv` file (`Content-Type: text/csv`). The CSV uses `;` as the column separator.

- **Mandatory columns:** `phonenumber`, `legalname`
- **Optional columns:** `lookupkey`, `evidenceaccesscontrolchallenge`, `evidenceaccesscontrolchallengeresponse`
- **Custom fields:** add extra columns prefixed with `*` (for example, `*orderid`); they are surfaced per recipient as `ExtraFields`.


**Example request body:**


```
phonenumber;legalname;lookupkey;*orderid
+34600000000;Acme Corp;SMS-001;ORD-001
+34600000001;Beta Ltd;SMS-002;ORD-002
```

| Response | Description |
|  --- | --- |
| `200 OK` | Recipients accepted. No response body is returned. |
| `400 Bad Request` | The payload is empty or the `Content-Type` is not `text/csv`. |
| `401 Unauthorized` | Authentication failed. |
| `404 Not Found` | No batch with the given `BatchId` was found. |
| `409 Conflict` | The recipient list failed validation (for example, missing mandatory columns). |


### Query batch recipients


```
QUERY /v2/EviSms/Batches/{BatchId}/Recipients
```

Lists the recipients of a batch, with cursor pagination. Filters are sent in a JSON request body: `Cursor`, `Limit` (1–1000), `SortDirection` (`Ascending`/`Descending`).

| Response | Description |
|  --- | --- |
| `200 OK` | Returns `{ "Cursor": "...", "Results": [...] }`. Each result includes the recipient fields and, once processed, the `EvidenceUniqueId` of the generated SMS. |
| `400 Bad Request` | Malformed request. |
| `401 Unauthorized` | Authentication failed. |
| `404 Not Found` | No batch with the given `BatchId` was found. |


### Delete all batch recipients


```
DELETE /v2/EviSms/Batches/{BatchId}/Recipients
```

| Response | Description |
|  --- | --- |
| `204 No Content` | Recipients removed. |
| `401 Unauthorized` | Authentication failed. |
| `404 Not Found` | No batch with the given `BatchId` was found. |


## States and outcomes

For a cross-service explanation of lifecycle terminology, see [States and outcomes](/products/namirialnotify/user-guides/states-outcomes). For a visual lifecycle reference, see the [EviSMS evidence lifecycle](/products/namirialnotify/user-guides/states-outcomes#evisms-evidence-lifecycle).

**States** represent the current step in the message lifecycle.

| State | Description |
|  --- | --- |
| `Draft` | Message is being prepared. |
| `New` | Message has been accepted by the platform. |
| `Ready` | Message is ready for dispatch. |
| `Dispatched` | The system has completed local processing; the message is ready to be sent to the telecommunications operator. |
| `Sent` | The SMS or RCS operator accepted the message for routing. |
| `Delivered` | Message was delivered to the recipient's device. |
| `Read` | Recipient opened the message (RCS only, where supported). |
| `Closed` | Message lifecycle is complete. |
| `Failed` | A recoverable processing or delivery failure occurred. The platform may retry or advance to a later state. |


**Outcomes** represent the overall result of the certification process.

| Outcome | Description |
|  --- | --- |
| `None` | No outcome determined yet. |
| `Certified` | Message certified with the configured certification level. |
| `Sent` | Message was sent. |
| `Delivered` | Message was delivered. |
| `Read` | Recipient opened the message (RCS only, where supported). |
| `Failed` | Delivery failed permanently. |


## Key request fields

### `IssuerName`

The legal name or short identifier for the sending organisation, recorded in the certification evidence. This is not the sender shown in the recipient's inbox — that sender is configured at the account level, separately from `IssuerName`.

### `CertificationLevel`

Defines the legal framework and geographic variant for certification. The API accepts `Standard`, `Advanced`, and regional values such as `Standard_EU`, `Advanced_EU`, `Standard_CO`, or `Advanced_MX`. Availability depends on the account.

### `DeliveryChannels`

An array specifying the delivery channels to use. Supported values: `RCS`, `SMS`. When both are specified, Namirial Notify attempts delivery in priority order.

### `TimeToLive`

The time in minutes during which the platform will attempt delivery before the message expires.

### `PushNotificationFilter`

An array of state names that trigger a callback to `PushNotificationUrl`. Valid values for EviSMS: `Ready`, `Sent`, `Dispatched`, `Delivered`, `Read`, `Failed`, `Closed`, `AffidavitPublished`.

`AffidavitPublished` is not a lifecycle state — it is a platform meta-event that fires when affidavit generation for this message completes.

### `AffidavitKinds`

The set of evidence events for which affidavits should be generated. Supported values: `Submitted`, `SubmittedAdvanced`, `TransmissionResult`, `DeliveryResult`, `Read`, `Closed`, `ClosedAdvanced`, `Complete`, `CompleteAdvanced`, `Event`.

### `EvidenceAccessControlMethod`

Controls how recipients access the evidence record. Supported values: `Public`, `Challenge`, `AutoChallenge`. When omitted, the account's configured default method applies.

`Challenge` requires the corresponding `EvidenceAccessControlChallenge` and `EvidenceAccessControlChallengeResponse` fields to be present. `AutoChallenge` uses a platform-generated challenge based on known recipient data and does not require those fields.

## OpenAPI specification

The OpenAPI 3.0.3 specification for the EviSMS API provides a machine-readable definition of the service endpoints, request and response schemas, authentication method, and error responses.

**Covered in the specification:**

- **Submit endpoint** (`POST /v1/EviSms/Submit`) — request and response schemas for SMS and RCS submissions, validation rules, and HTTP status codes
- **Query endpoint** (`GET /v1/EviSms/Query`) — pagination parameters, filtering options, state and outcome enums, and result structure
- **Authentication** — HTTP Basic authentication requirements
- **Error handling** — error response structure with error codes and diagnostic information
- **Data types** — schema definitions for documented messages, recipients, delivery channels, and affidavits


The OpenAPI spec can be used to generate client libraries, integration tests, or interactive API documentation.

[View OpenAPI spec →](/products/namirialnotify/apis/oas/evisms-api)

## Related

- [EviSMS](/products/namirialnotify/services/evisms)
- [EviMail API](/products/namirialnotify/apis/evimail-api)
- [EviNotice API](/products/namirialnotify/apis/evinotice-api)
- [EviPost API](/products/namirialnotify/apis/evipost-api)
- [API documentation](/products/namirialnotify/dev/api-documentation)
- [Callbacks and webhooks](/products/namirialnotify/dev/callbacks)
- [Error handling](/products/namirialnotify/dev/error-handling)
- [Integration workflows](/products/namirialnotify/dev/integration-patterns)
- [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)