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

# Quick Start

> First push send: create app, register Web device, and dispatch a notification.

<Tip>
  From **zero to your first push in the queue** in a few steps: **Push App** → **registered device** → **send** with device IDs in `to`.
</Tip>

## In short

* **Create a Push App**, Web VAPID is generated automatically on create.
* **Register each device** when the user accepts in the browser and save the **device ID**.
* **Dispatch notifications** by passing device IDs in **`to`** (up to **100** per call).

Context: [Introduction](/en/push-api/como-funciona/introducao). Scopes: [API Key scopes](/en/push-api/como-funciona/escopos-da-api-key).

## Before you start

* Key with **`push:apps:manage`**, **`push:devices:register`**, and **`push:send`** (or admin scope in testing)
* Plan with push enabled
* Auth: `Authorization: Bearer sk_live_...` or `x-api-key`
* Base URL: `https://api.notifique.dev`, use `sk_test_...` in [Sandbox](/en/guides/sandbox/index) when getting started

<Note>
  A key with **`pushAppIds`** in the dashboard only sends to devices from those apps. Another app → **403** (`PUSH_APP_NOT_ALLOWED`).
</Note>

***

## 1. Create Push App

Two paths, pick what fits your integration:

#### 1A, Via dashboard

1. Push → **New app**
2. Enter the product **name**
3. Note the app **`id`** and **VAPID public key** (for the site)

#### 1B, Via API

```http theme={null}
POST /v1/push/apps
Content-Type: application/json
Authorization: Bearer sk_live_xxxxx
```

```json theme={null}
{
  "name": "My App"
}
```

Expected response: **200** with VAPID generated automatically:

```json theme={null}
{
  "success": true,
  "data": {
    "id": "clxxapp...",
    "name": "My App",
    "vapidPublicKey": "BEl62iU...",
    "hasVapidPrivate": true,
    "hasFcm": false,
    "hasApns": false,
    "createdAt": "2025-02-15T10:00:00.000Z"
  }
}
```

Scope: **`push:apps:manage`**. Save the **`id`** and use `vapidPublicKey` on the front end to register the subscription.

### Custom VAPID (optional)

To use your own key pair instead of the generated one:

```http theme={null}
PUT /v1/push/apps/:id
Content-Type: application/json
Authorization: Bearer sk_live_xxxxx
```

```json theme={null}
{
  "name": "My App",
  "vapidPublicKey": "BEl62iU...",
  "vapidPrivateKey": "UUxI4S..."
}
```

The **private** key stays on Notifique; the **public** key goes on your site.

***

## 2. Register device

When the user grants permission in the browser, send the **subscription** to your backend and register via API:

```http theme={null}
POST /v1/push/devices
Content-Type: application/json
Authorization: Bearer sk_live_xxxxx
```

```json theme={null}
{
  "appId": "clxxapp...",
  "platform": "web",
  "subscription": {
    "endpoint": "https://fcm.googleapis.com/fcm/send/...",
    "keys": {
      "p256dh": "BEl62iU...",
      "auth": "tBH2..."
    }
  },
  "externalUserId": "user_123"
}
```

Expected response: **200**:

```json theme={null}
{
  "success": true,
  "data": {
    "id": "clxxdevice...",
    "appId": "clxxapp...",
    "platform": "web",
    "externalUserId": "user_123",
    "createdAt": "2025-02-15T10:05:00.000Z"
  }
}
```

Save the device **`id`**, that goes in `to` when sending. Scope: **`push:devices:register`**.

<Note>
  **Public** registration (no API Key) also exists for front-end flows, only `appId` + `subscription`. With a key, the scope above is required.
</Note>

***

## 3. Send notification

Up to **100** device IDs per call. At least **title** or **body** is required. Each send consumes **1 credit**.

```http theme={null}
POST /v1/push/messages
Content-Type: application/json
Authorization: Bearer sk_live_xxxxx
```

```json theme={null}
{
  "to": ["clxxdevice..."],
  "type": "push",
  "payload": {
    "title": "Hello!",
    "body": "You have a new message.",
    "url": "https://yoursite.com/notifications",
    "icon": "https://yoursite.com/icon.png"
  },
  "options": { "priority": "normal" }
}
```

At least **title** or **body** in `payload` is required.

### Send with template

If you already have a [workspace template](/en/template-api/como-funciona/variaveis-disponiveis-e-crud) with push enabled:

```json theme={null}
{
  "to": ["clxxdevice..."],
  "type": "template",
  "payload": {
    "templateId": "TEMPLATE_ID",
    "variables": { "name": "Maria" }
  }
}
```

Expected response: **202**

```json theme={null}
{
  "success": true,
  "data": {
    "status": "QUEUED",
    "count": 1,
    "messageIds": ["clpush1..."],
    "pushIds": ["clpush1..."]
  }
}
```

`messageIds` is the canonical field; `pushIds` is a compatibility alias. Scope: **`push:send`**.

**Schedule**, include `schedule.sendAt` (ISO 8601) in the body. **Webhook for this batch only:** `options.webhook` with `url` and `secret`.

***

## 4. Query, list, and cancel

**List sends**

```http theme={null}
GET /v1/push/messages?page=1&limit=20
Authorization: Bearer sk_live_xxxxx
```

Optional filters: `status`, `appId`. Scope: **`push:read`**.

**View one send**

```http theme={null}
GET /v1/push/messages/:id
Authorization: Bearer sk_live_xxxxx
```

**Cancel scheduled** (only **SCHEDULED** status):

```http theme={null}
POST /v1/push/messages/:id/cancel
Authorization: Bearer sk_live_xxxxx
```

Scheduled credit returns to the workspace.

***

## 5. Avoid duplicates

**`Idempotency-Key`** header on the send `POST`. Repeats within 24 h do not create duplicate pushes. See [Security and reliability](/en/guides/conceitos/seguranca-e-confiabilidade).

***

## 6. Webhooks (optional)

Configure `push.sent`, `push.delivered`, `push.clicked`, `push.failed`, and `push.cancelled` to track without polling.

Guide: [Webhook events](/en/push-api/como-funciona/eventos-do-webhooks).

***

## All send types

In the API reference (Push tab), open **Send push notification** and pick an example in the playground: Full push, Template, Scheduled.

## Next steps

* [Introduction](/en/push-api/como-funciona/introducao): when to use and status lifecycle
* [Scopes](/en/push-api/como-funciona/escopos-da-api-key): key permissions
* [Webhook events](/en/push-api/como-funciona/eventos-do-webhooks): real-time status
* [Error responses](/en/guides/conceitos/resposta-de-erros): HTTP codes and `code`
