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

# Watermark Embed Quickstart

> Embed invisible watermarks into your images

This guide walks you through embedding an invisible watermark into an image — from creating an order to downloading the watermarked result.

## Prerequisites

* A BIZ MORI API key ([get one here](https://app.bizmori.com/keys))
* An image or PDF file to watermark (`jpeg`, `jpg`, `png`, `webp`, `tiff`, `bmp`, or `pdf`)

## Step 1: Create an order

Create a watermark embed order with your watermark text.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.bizmori.com/api/v2/orders/wtr-embed \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "idempotencyKey": "my-embed-001",
      "files": [
        {
          "fileName": "photo.jpg",
          "watermarks": [{ "text": "MORI_WATERMARK" }]
        }
      ]
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.bizmori.com/api/v2/orders/wtr-embed', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      idempotencyKey: 'my-embed-001',
      files: [
        {
          fileName: 'photo.jpg',
          watermarks: [{ text: 'MORI_WATERMARK' }],
        },
      ],
    }),
  });
  const { data } = await response.json();
  ```

  ```python Python theme={null}
  import requests

  res = requests.post(
      'https://api.bizmori.com/api/v2/orders/wtr-embed',
      headers={'Authorization': 'Bearer YOUR_API_TOKEN'},
      json={
          'idempotencyKey': 'my-embed-001',
          'files': [
              {
                  'fileName': 'photo.jpg',
                  'watermarks': [{'text': 'MORI_WATERMARK'}],
              }
          ],
      },
  )
  data = res.json()['data']
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "data": {
    "orderName": "wtr_embed_2026-03-18",
    "orderId": "123456789",
    "status": "pending",
    "files": [
      {
        "fileId": 1,
        "fileName": "photo.jpg",
        "uploadUrl": "https://s3.amazonaws.com/...",
        "fileKey": "wtr-embed/123456789/images/1/photo.jpg",
        "fileFormat": "JPG",
        "fileType": "IMG"
      }
    ]
  }
}
```

## Step 2: Upload files

PUT your file to the presigned `uploadUrl` from Step 1. This is a direct S3 upload — **no Authorization header needed**.

```bash cURL theme={null}
curl -X PUT "https://s3.amazonaws.com/..." \
  -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg
```

<Info>
  **No confirm step needed.** Unlike Anti-AI and AI Detection, Watermark Embed processing starts automatically after your file upload completes. Proceed directly to checking the order status.
</Info>

<Note>
  Presigned URLs expire after **1 hour**. If yours has expired, use the [Refresh URLs](/api-reference/orders/refresh-urls) endpoint to generate new ones.
</Note>

## Step 3: Check order status & download result

Poll the order or use [webhooks](/webhooks) to receive a push notification when processing completes.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.bizmori.com/api/v2/orders/123456789 \
    -H "Authorization: Bearer YOUR_API_TOKEN"
  ```

  ```javascript Node.js theme={null}
  const res = await fetch('https://api.bizmori.com/api/v2/orders/123456789', {
    headers: { 'Authorization': 'Bearer YOUR_API_TOKEN' },
  });
  const { data } = await res.json();
  // data.status: 'pending' | 'inProgress' | 'complete' | 'failed'
  ```

  ```python Python theme={null}
  res = requests.get(
      'https://api.bizmori.com/api/v2/orders/123456789',
      headers={'Authorization': 'Bearer YOUR_API_TOKEN'},
  )
  status = res.json()['data']['status']
  ```
</CodeGroup>

| Status       | Meaning                 |
| ------------ | ----------------------- |
| `pending`    | Waiting for file upload |
| `inProgress` | Processing              |
| `complete`   | Ready for download      |
| `failed`     | Processing failed       |

Once `status` is `complete`, fetch the download URL:

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.bizmori.com/api/v2/orders/123456789/download \
    -H "Authorization: Bearer YOUR_API_TOKEN"
  ```

  ```javascript Node.js theme={null}
  const res = await fetch('https://api.bizmori.com/api/v2/orders/123456789/download', {
    headers: { 'Authorization': 'Bearer YOUR_API_TOKEN' },
  });
  const { data } = await res.json();
  // data.downloadUrl — valid for 1 hour
  ```

  ```python Python theme={null}
  res = requests.get(
      'https://api.bizmori.com/api/v2/orders/123456789/download',
      headers={'Authorization': 'Bearer YOUR_API_TOKEN'},
  )
  download_url = res.json()['data']['downloadUrl']
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "data": {
    "downloadUrl": "https://s3.amazonaws.com/...",
    "expiresIn": 3600
  }
}
```

The `downloadUrl` is a presigned S3 URL valid for **1 hour**.

## Error handling

| HTTP Status | Meaning               | Action                                   |
| ----------- | --------------------- | ---------------------------------------- |
| `400`       | Invalid request       | Check parameters and file format         |
| `401`       | Authentication failed | Verify your API key                      |
| `429`       | Rate limit exceeded   | Reduce request frequency or upgrade plan |

For the complete error code reference, see [Error Codes](/errors).

## Next steps

<CardGroup cols={2}>
  <Card title="Anti-AI" icon="shield" href="/quickstart/anti-ai">
    Protect images from AI training and generation.
  </Card>

  <Card title="Watermark Extract" icon="magnifying-glass" href="/quickstart/watermark-extract">
    Detect and extract watermarks from images.
  </Card>

  <Card title="AI Detection" icon="robot" href="/quickstart/ai-detection">
    Detect AI-generated images with probability scores.
  </Card>

  <Card title="Webhooks" icon="bell" href="/webhooks">
    Set up webhooks to get notified when processing completes.
  </Card>
</CardGroup>
