# Wapifly WhatsApp API

> This document is written for developers and AI coding assistants. Use the whole file as context when writing a Wapifly API integration. Do not invent endpoints, parameters or fields that are not listed here.

## Summary

- Base URL: `https://www.wapifly.com/api/{number}`
- `{number}`: your WhatsApp number registered on Wapifly, with country code, without `+` (e.g. `905321234567`).
- Authentication: `wapikey: <64-character API key>` header on every request.
- `Content-Type: application/json` for requests with a body.
- Requests are only accepted from IP addresses allowed in the Control Panel (otherwise `errCode: 108`).
- `Accept-Language: tr` or `en` sets the language of response texts.
- All responses are JSON. Success: `"status": "ok"`. Error: `"status": "fail"` + `errCode` + `message`. Branch on `errCode`, not on the `message` text.

## Sending flow (important)

Sending is **asynchronous**:

1. (Optional) Check that the number is on WhatsApp with `GET /{number}/check-contact/{phone}`.
2. `POST /{number}/send-message` queues the job and immediately returns an `id`. `"status": "ok"` only means the request was **accepted**, not that the message was sent.
3. Messages are sent one by one in the background, `interval` seconds apart. Numbers that are unregistered, invalid or blacklisted fail at this stage.
4. Query the result with `GET /{number}/message-status/{id}`. Poll at intervals (e.g. 5-10 s) until `message.waiting` is 0. Per-number results are in `message.list[]`.

The "sent" status means the message was accepted by WhatsApp servers. Delivered / read information is **not** available in the API.

## Endpoint list

- `GET /{number}/status` — Service Status
- `POST /{number}/repair` — Repair Service
- `POST /{number}/send-message` — Send Message
- `GET /{number}/message-status/{id}` — Message Status
- `GET /{number}/check-contact/{phone}` — Check Contact
- `GET /{number}/contacts` — Contacts
- `GET /{number}/blacklist` — Get Blacklist
- `POST /{number}/blacklist` — Add to Blacklist
- `DELETE /{number}/blacklist` — Remove from Blacklist
- `GET /{number}/get-channels` — Channels
- `GET /{number}/get-groups` — Groups

## Service Status

`GET /{number}/status`

Shows whether your WhatsApp session is connected and ready to send messages. Use it as a check before sending.

Takes no parameters.

### Example request

```bash
curl -X GET "https://www.wapifly.com/api/905XXXXXXXXX/status" \
  -H "wapikey: API_ANAHTARINIZ"
```

### Responses

HTTP 200 — Service is running

```json
{
  "status": "ok",
  "message": "Hizmetiniz çalışıyor.",
  "state": "ready",
  "isReady": true,
  "lastActivity": "2026-10-14T12:42:10.000Z"
}
```

HTTP 200 — Service is not running

```json
{
  "status": "fail",
  "message": "Hizmetiniz çalışmıyor.",
  "state": "disconnected",
  "isReady": false,
  "lastActivity": "2026-10-14T12:42:10.000Z"
}
```

HTTP 500 — Session not found

```json
{
  "status": "fail",
  "errCode": 110,
  "message": "Yeniden QR kod okutmalısınız."
}
```

### `state` values

| Value | Description |
|---|---|
| `ready` | Connected, messages can be sent. |
| `initializing` | Session is starting. |
| `connecting` | Connecting to WhatsApp. |
| `authenticated` | Logged in, getting ready. |
| `qr_ready` | Waiting for QR scan. Scan the QR code from the Control Panel. |
| `disconnected` | Disconnected. Try reconnecting with Repair Service. |
| `failed` | Session failed to start. |

## Repair Service

`POST /{number}/repair`

Reconnects a disconnected WhatsApp session. Does nothing if the service is already running. If the session has been closed entirely it cannot be repaired; scan the QR code again from the Control Panel.

Takes no parameters.

### Example request

```bash
curl -X POST "https://www.wapifly.com/api/905XXXXXXXXX/repair" \
  -H "wapikey: API_ANAHTARINIZ"
```

### Responses

HTTP 200 — Repaired

```json
{
  "status": "ok",
  "message": "Hizmetiniz başarıyla onarıldı."
}
```

HTTP 200 — Service already running

```json
{
  "status": "ok",
  "message": "Hizmetiniz çalışıyor."
}
```

HTTP 401 — QR code must be scanned again

```json
{
  "status": "fail",
  "errCode": 109,
  "message": "Hizmet onarımı başarısız oldu. Yeniden QR kod okutmalısınız."
}
```

> After a repair, wait a few seconds and check with Service Status that the session is `ready`.

## Send Message

`POST /{number}/send-message`

Sends a text, image, document, audio or video message to one or more numbers (or a WhatsApp channel). The request queues the job and immediately returns a job ID; messages are sent one by one in the background at the interval you set. Call Message Status with the returned ID to get the result for each number.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `type` | body | integer | no | Message type. `1` text (default), `2` image, `3` document, `4` audio, `5` video. Only types included in your plan can be used. |
| `numbers` | body | string | yes | Recipient numbers. Separate multiple numbers with commas or line breaks. Include the country code (e.g. `905321234567`). Duplicates are sent once. Not needed when `channel` is used. |
| `message` | body | string | no | Message text. Required for `type=1`; sent as the caption for images, documents and videos; ignored for audio. Spintax is supported: `{Hello\|Hi}`. |
| `url` | body | string | no | URL of the file to send. Required for `type` 2-5 and must start with `https://`. |
| `interval` | body | integer | no | Delay between two messages in seconds. Default and minimum is `1`. |
| `channel` | body | string | no | Channel ID (`...@newsletter`) to send to a WhatsApp channel instead of numbers. Get channel IDs from the Channels service. |
| `channelname` | body | string | no | Channel name shown in reports. |
| `autoblacklist` | body | boolean | no | If `true`, numbers that fail are added to the blacklist automatically. |
| `blacklistlink` | body | boolean | no | If `true`, an unsubscribe link is appended to the message. Your plan must include the unsubscribe link feature. |

### Example request

```bash
curl -X POST "https://www.wapifly.com/api/905XXXXXXXXX/send-message" \
  -H "wapikey: API_ANAHTARINIZ" \
  -H "Content-Type: application/json" \
  -d '{"type":1,"numbers":"905321234567,905441234567","message":"Merhaba, siparişiniz kargoya verildi.","interval":5}'
```

### Responses

HTTP 200 — Job queued

```json
{
  "status": "ok",
  "id": "6710A2F4C3B1E2D4F5A6B7C8",
  "message": "Mesajınız gönderiliyor. Gönderim durumunu görmek için /message-status servisini çağırın."
}
```

HTTP 400 — Invalid parameter

```json
{
  "status": "fail",
  "errCode": 302,
  "message": "En az 1 numara girmelisiniz."
}
```

HTTP 404 — WhatsApp session not ready

```json
{
  "status": "fail",
  "errCode": 404,
  "type": "danger",
  "title": "Hata Oluştu!",
  "message": "Hizmetinizde geçici bir problem yaşanıyor. Kontrol panelinizden onarım yapmalısınız."
}
```

> A `"status": "ok"` response means the messages were **queued**, not delivered. Numbers that are not on WhatsApp are queued too and marked as failed during sending. Use Check Contact to verify numbers before sending.

## Message Status

`GET /{number}/message-status/{id}`

Alternative: `POST /{number}/message-status` — Can also be called with POST, sending the ID as `id` in the body.

Returns the overall status of a job and the result for each number, using the ID returned by Send Message.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | The `id` value from the Send Message response. |

### Example request

```bash
curl -X GET "https://www.wapifly.com/api/905XXXXXXXXX/message-status/6710A2F4C3B1E2D4F5A6B7C8" \
  -H "wapikey: API_ANAHTARINIZ"
```

### Responses

HTTP 200 — Success

```json
{
  "status": "ok",
  "message": {
    "status": "Tamamlandı",
    "date": "14.10.2026 15:42:10",
    "count": 3,
    "success": 1,
    "failed": 1,
    "waiting": 1,
    "list": [
      {
        "number": "905321234567",
        "status": "Gönderildi",
        "info": "Gönderildi",
        "tarih": "14.10.2026 15:42:11"
      },
      {
        "number": "905441234567",
        "status": "Gönderilemedi",
        "info": "WhatsApp Kullanmıyor.",
        "tarih": "14.10.2026 15:42:16"
      },
      {
        "number": "905551234567",
        "status": "Gönderilecek",
        "info": "Gönderilecek",
        "tarih": "14.10.2026 15:42:21"
      }
    ]
  }
}
```

HTTP 400 — ID not found

```json
{
  "status": "fail",
  "errCode": 312,
  "message": "Geçersiz ID."
}
```

### Number statuses

| Value | Description |
|---|---|
| `Gönderildi` | Sent: the message was accepted by WhatsApp servers. It does not indicate delivery to the recipient's phone or that it was read. |
| `Gönderilemedi` | Failed. The reason is in `info`: e.g. not on WhatsApp, invalid number, blacklisted, cancelled. |
| `Gönderilecek` | Waiting: not sent yet. |

> Status texts are returned in Turkish or English based on the `Accept-Language` header.

## Check Contact

`GET /{number}/check-contact/{phone}`

Alternative: `POST /{number}/check-contact` — Can also be called with POST, sending the number as `phone` in the body.

Checks whether a number is registered on WhatsApp. Use it to filter out invalid numbers before a bulk send.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `phone` | path | string | yes | Number to check, with country code (e.g. `905321234567`). |

### Example request

```bash
curl -X GET "https://www.wapifly.com/api/905XXXXXXXXX/check-contact/905321234567" \
  -H "wapikey: API_ANAHTARINIZ"
```

### Responses

HTTP 200 — Number is on WhatsApp

```json
{
  "status": "ok",
  "number": "905321234567",
  "isRegistered": true
}
```

HTTP 200 — Number is not on WhatsApp

```json
{
  "status": "ok",
  "number": "905321234567",
  "isRegistered": false
}
```

HTTP 400 — Invalid number

```json
{
  "status": "fail",
  "errCode": 205,
  "message": "Geçersiz telefon numarası."
}
```

HTTP 503 — WhatsApp session not responding

```json
{
  "status": "fail",
  "errCode": 112,
  "message": "Hizmetinizde geçici bir problem yaşanıyor. Kontrol panelinizden onarım yapmalısınız."
}
```

> This service queries WhatsApp live. Checking many numbers back to back may get your number restricted; leave a delay between checks.

## Contacts

`GET /{number}/contacts`

Lists the contacts in your WhatsApp number's address book. Your plan must include the contacts feature.

Takes no parameters.

### Example request

```bash
curl -X GET "https://www.wapifly.com/api/905XXXXXXXXX/contacts" \
  -H "wapikey: API_ANAHTARINIZ"
```

### Responses

HTTP 200 — Success

```json
{
  "status": "ok",
  "contacts": [
    {
      "id": "905321234567@s.whatsapp.net",
      "name": "Ahmet Yılmaz",
      "number": "905321234567",
      "isMyContact": true
    }
  ]
}
```

HTTP 403 — Not included in plan

```json
{
  "status": "fail",
  "errCode": 203,
  "message": "Paketiniz WhatsApp rehberini desteklemiyor."
}
```

> The contact list is cached for 1 hour. Contacts newly added to your phone appear within an hour.

## Get Blacklist

`GET /{number}/blacklist`

Lists the numbers in your blacklist and how they were added. Messages are not sent to blacklisted numbers through Send Message; they appear as blacklisted in the job report.

Takes no parameters.

### Example request

```bash
curl -X GET "https://www.wapifly.com/api/905XXXXXXXXX/blacklist" \
  -H "wapikey: API_ANAHTARINIZ"
```

### Responses

HTTP 200 — Success

```json
{
  "status": "ok",
  "blacklist": [
    {
      "number": "905321234567",
      "source": "API"
    },
    {
      "number": "905441234567",
      "source": "İptal Linki"
    }
  ]
}
```

### `source` values

| Value | Description |
|---|---|
| `API` | Added through the API. |
| `Web Panel` | Added from the Control Panel. |
| `Otomatik` | Added automatically because sending failed while `autoblacklist` was on. |
| `İptal Linki` | The recipient clicked the unsubscribe link in a message. |

## Add to Blacklist

`POST /{number}/blacklist`

Adds numbers to the blacklist. Numbers already in the list are not added again.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `numbers` | body | string | yes | Numbers to add. Separate multiple numbers with commas or line breaks. |

### Example request

```bash
curl -X POST "https://www.wapifly.com/api/905XXXXXXXXX/blacklist" \
  -H "wapikey: API_ANAHTARINIZ" \
  -H "Content-Type: application/json" \
  -d '{"numbers":"905321234567,905441234567"}'
```

### Responses

HTTP 200 — Success

```json
{
  "status": "ok",
  "message": "Numaralar kara listeye eklendi."
}
```

HTTP 400 — No valid number

```json
{
  "status": "fail",
  "errCode": 202,
  "message": "En az 1 numara girmelisiniz."
}
```

## Remove from Blacklist

`DELETE /{number}/blacklist`

Removes numbers from the blacklist. Numbers not in the list are ignored.

### Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `numbers` | body | string | yes | Numbers to remove. Separate multiple numbers with commas or line breaks. |

### Example request

```bash
curl -X DELETE "https://www.wapifly.com/api/905XXXXXXXXX/blacklist" \
  -H "wapikey: API_ANAHTARINIZ" \
  -H "Content-Type: application/json" \
  -d '{"numbers":"905321234567"}'
```

### Responses

HTTP 200 — Success

```json
{
  "status": "ok",
  "message": "Numaralar kara listeden silindi."
}
```

HTTP 400 — No valid number

```json
{
  "status": "fail",
  "errCode": 202,
  "message": "En az 1 numara girmelisiniz."
}
```

## Channels

`GET /{number}/get-channels`

Lists the channels managed by your WhatsApp number. Use the returned `id` as the `channel` parameter of Send Message. Your plan must include the channel feature.

Takes no parameters.

### Example request

```bash
curl -X GET "https://www.wapifly.com/api/905XXXXXXXXX/get-channels" \
  -H "wapikey: API_ANAHTARINIZ"
```

### Responses

HTTP 200 — Success

```json
{
  "status": "ok",
  "channels": [
    {
      "id": "120363012345678901@newsletter",
      "name": "Kampanyalar"
    }
  ]
}
```

HTTP 403 — Not included in plan

```json
{
  "status": "fail",
  "errCode": 204,
  "message": "Paketiniz WhatsApp kanal mesajını desteklemiyor."
}
```

> The list is cached for 1 hour.

## Groups

`GET /{number}/get-groups`

Lists the groups your WhatsApp number is a member of. Your plan must include the channel feature.

Takes no parameters.

### Example request

```bash
curl -X GET "https://www.wapifly.com/api/905XXXXXXXXX/get-groups" \
  -H "wapikey: API_ANAHTARINIZ"
```

### Responses

HTTP 200 — Success

```json
{
  "status": "ok",
  "groups": [
    {
      "id": "120363098765432109@g.us",
      "name": "Bayiler",
      "isGroup": true,
      "timestamp": 1728909730
    }
  ]
}
```

HTTP 403 — Not included in plan

```json
{
  "status": "fail",
  "errCode": 204,
  "message": "Paketiniz WhatsApp kanal mesajını desteklemiyor."
}
```

> The list is cached for 1 hour.

## Error codes

| errCode | HTTP | Description |
|---|---|---|
| 100 | 401 | `wapikey` header is missing or malformed. |
| 101 | 400 | WhatsApp number is missing from the URL. |
| 102 | 401 | WhatsApp number or API key is incorrect. |
| 103 | 401 | Service is inactive. |
| 104 | 401 | Service setup is not complete. |
| 105 | 401 | Service is busy; it will be ready in 1-2 minutes. |
| 106 | 401 | Service has expired. |
| 107 | 401 | API access is disabled. Enable it in the Control Panel. |
| 108 | 401 | Request came from an IP that is not allowed. Add the `IP` value from the response to the allowed IPs in the Control Panel. |
| 109 | 401 | Repair failed. Scan the QR code again. |
| 110 | 500 | Session not found. Scan the QR code again. |
| 111 | 500 | The WhatsApp service returned an error. See `message` for details. |
| 112 | 503 | WhatsApp session is not responding. Run Repair Service. |
| 201 | 401 | Service not found. |
| 202 | 400 | No valid number given. |
| 203 | 403 | Your plan does not include contacts. |
| 204 | 403 | Your plan does not include channels. |
| 205 | 400 | Invalid phone number. |
| 301 | 400 | Invalid message type (`type`). |
| 302 | 400 | No valid number given. |
| 303 | 400 | `interval` cannot be less than 1 second. |
| 304 | 400 | Invalid URL. It must start with `https://`. |
| 305 | 400 | Message cannot be empty. |
| 306 | 500 | An unexpected error occurred. |
| 307 | 404 | Service not found. |
| 308 | 403 | Your plan does not support text messages. |
| 309 | 403 | Your plan does not support image, video or channel messages. |
| 310 | 403 | Your plan does not support document messages. |
| 311 | 403 | Your plan does not support audio messages. |
| 312 | 400 | Invalid job ID. |
| 313 | 400 | Invalid channel ID. It must end with `@newsletter`. |
| 404 | 404 | The WhatsApp session was not ready when sending. Run Repair Service. |
