---
url: https://textme-docs.matat.io/reference/dlr-statuses.md
description: >-
  Every delivery-report status with its Hebrew message and an English gloss, and
  how to bucket them into delivered, unconfirmed, blocked and failed.
---

# DLR statuses

The `status` carried by each entry in a delivery report. Inside `transactions[]` from [`dlr`](../endpoints/reports.md) and [`dlrByDate`](../endpoints/reports.md), and in the `status` field of a [pushed DLR](../endpoints/push.md).

This is a different scale from the [request status codes](./status-codes.md), which say whether the API accepted your call. Here, `0` and `102` both mean *delivered*; the top-level `0` on the same response only means *the report was produced*.

Each transaction also carries `he_message` and `en_message`. The same status spelled out in Hebrew and English. The English column below is that gloss.

## Delivered

| Status | `he_message` | Meaning |
|---|---|---|
| `0` | הגיע ליעד | Delivered to the handset. |
| `102` | הגיע ליעד | Delivered to the handset. The value most live traffic settles on. |

## Sent, outcome unknown

| Status | `he_message` | Meaning |
|---|---|---|
| `-1` | נשלח - ללא אישור מסירה | Sent, but the carrier returned no delivery confirmation. Not a failure, simply unconfirmed. |
| `2` | Timeout | No confirmation arrived within the carrier's window. |

## Not delivered

| Status | `he_message` | Meaning |
|---|---|---|
| `1` | נכשל | Failed. |
| `3` | נכשל | Failed. |
| `4` | נכשל סלולר | Failed at the mobile network. |
| `5` | נכשל | Failed. |
| `6` | נכשל | Failed. |
| `14` | נכשל סלולר - עבר תהליך של store\&forward | Failed at the mobile network after the store-and-forward retry cycle. the network held the message and still could not deliver it. |
| `101` | לא הגיע ליעד | Not delivered. |
| `103` | פג תוקף | Expired before it could be delivered, typically a handset that stayed unreachable. |
| `104` | נמחק | Deleted before delivery. |
| `105` | לא הגיע ליעד | Not delivered. |
| `106` | לא הגיע ליעד | Not delivered. |
| `107` | לא הגיע ליעד | Not delivered. |
| `108` | נדחה | Rejected by the network. |
| `109` to `132` | לא הגיע ליעד | Not delivered. A block of carrier-specific failure codes that all mean the same thing to you. |
| `747` | מנוי נמצא מחוץ לכיסוי רשת מקומית | Subscriber outside local network coverage, roaming or out of range. |

## Blocked or refused

These are policy outcomes, not network faults. A number that produces them will keep producing them until something changes on the account or the subscriber's side.

| Status | `he_message` | Meaning |
|---|---|---|
| `15` | מספר כשר | A kosher (filtered) handset, which does not accept regular SMS. Reach these with a [voice message](../endpoints/tts.md) instead. `tts.type` `2` routes SMS to normal handsets and a call to filtered ones automatically. |
| `16` | אין הרשאת שעת שליחה | Sending was not permitted at that hour. |
| `17` | חסום להודעות פירסומיות | The subscriber is blocked for marketing messages. |
| `18` | הודעה לא חוקית | The message was judged illegal or non-compliant. |
| `201` | נחסם לפי בקשה | Blocked at the subscriber's own request. an opt-out. See [Opt-out & compliance](../use-cases/opt-out-and-compliance.md). |

## Account and system

| Status | `he_message` | Meaning |
|---|---|---|
| `7` | אין יתרה | No credit at the moment of sending. |
| `998` | אין הרשאה | Not authorised. |
| `999` | שגיאה לא ידועה | Unknown error. |

## Reading them in code

Rather than switching on every value, sort them into the four outcomes that actually drive behaviour:

::: code-group

```js [JavaScript]
const DELIVERED = new Set(['0', '102'])
const PENDING = new Set(['-1', '2'])
const BLOCKED = new Set(['15', '16', '17', '18', '201'])

function outcome(status) {
  const code = String(status)

  if (DELIVERED.has(code)) return 'delivered'
  if (PENDING.has(code)) return 'unconfirmed'
  if (BLOCKED.has(code)) return 'blocked' // do not retry this number
  return 'failed'
}
```

```python [Python]
DELIVERED = {"0", "102"}
PENDING = {"-1", "2"}
BLOCKED = {"15", "16", "17", "18", "201"}


def outcome(status):
    code = str(status)

    if code in DELIVERED:
        return "delivered"
    if code in PENDING:
        return "unconfirmed"
    if code in BLOCKED:
        return "blocked"  # do not retry this number
    return "failed"
```

```php [PHP]
<?php

const TEXTME_DELIVERED = ['0', '102'];
const TEXTME_PENDING = ['-1', '2'];
const TEXTME_BLOCKED = ['15', '16', '17', '18', '201'];

function textme_outcome(string|int $status): string
{
    $code = (string) $status;

    return match (true) {
        in_array($code, TEXTME_DELIVERED, true) => 'delivered',
        in_array($code, TEXTME_PENDING, true) => 'unconfirmed',
        in_array($code, TEXTME_BLOCKED, true) => 'blocked', // do not retry
        default => 'failed',
    };
}
```

:::

`unconfirmed` is worth keeping separate from `failed`. A `-1` usually did arrive; treating it as a failure and resending means charging yourself twice to deliver one message.
