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

# Test API keys

> Exercise the BIZ MORI order lifecycle without processing files or consuming credits.

Use the automatically issued test API key with the `sk_test_` prefix to validate your integration before you use a live API key.

Test API keys use the same Bearer authentication as live keys, but they do not run Anti-AI, watermark, or AI Detection processing. They also do not create result files or consume customer credits.

> [!NOTE]
>
> Persistent test orders and test webhooks are enabled per environment. If your environment returns synthetic orders that are not retained, it is using the legacy mock behavior. Use a live API key when you need to evaluate processing quality or download a result file.

## Test order lifecycle

**1. Create an order**

Call the same order creation endpoint that you use for a live integration. Send the test key in the `Authorization` header and provide an `idempotencyKey`. Generate a new UUIDv4 for each logical order, and reuse it only when retrying that same request after a network failure.

```bash theme={null}
curl -X POST https://api.bizmori.com/api/v2/orders/anti-ai \
  -H "Authorization: Bearer $BIZMORI_TEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotencyKey": "2f1c3e4a-8b57-4a6d-9c20-7e5f1a3b6d42",
    "files": [{"fileName": "sample.png"}]
  }'
```

**2. Upload the test file**

For an upload-mode test order, send the file to the `uploadUrl` returned by the order response. A test upload URL uses the `PUT /api/v2/test-uploads/{token}` route.

The upload URL carries its own authorization. Do not add an API key header. BIZ MORI consumes the request stream, records upload completion, and discards the file contents.

```bash theme={null}
curl -X PUT "TEST_UPLOAD_URL" \
  --data-binary @sample.png
```

The default test upload limit is 50 MiB. Use [Refresh presigned URLs](https://docs.contentcare.ai/api-reference/orders/refresh-urls.md) when an upload URL expires and the order is still waiting for an upload.

**3. Confirm when the service requires it**

Call the confirm endpoint after the upload for Anti-AI upload mode and AI Detection. Watermark Embed and Watermark Extract start after their required uploads finish. Anti-AI URL mode starts when you create the order.

**4. Observe the state transition**

Test orders follow the same state shape as live orders:

`pending → inProgress → complete` or `failed`

The simulated processing delay is about five seconds. Poll [Get order details](https://docs.contentcare.ai/api-reference/orders/get-order-v3.md), or use a test webhook endpoint when webhooks are enabled in your environment.

**5. Inspect the test order**

Use [List orders](https://docs.contentcare.ai/api-reference/orders/list-orders.md), [Recent usage statistics](https://docs.contentcare.ai/api-reference/orders/recent-stats.md), and [Get order details](https://docs.contentcare.ai/api-reference/orders/get-order-v3.md) with the same test key. You see only test orders owned by the account associated with that key.

## Service flows

| Service | Create | Upload | Confirm |
| - | - | - | - |
| Anti-AI upload mode | `POST /api/v2/orders/anti-ai` | Test upload URL | Required |
| Anti-AI URL mode | `POST /api/v2/orders/anti-ai` | Not required | Not required |
| Watermark Embed | `POST /api/v3/orders/wtr-embed` | Test upload URL | Not required |
| Watermark Extract | `POST /api/v3/orders/wtr-extract` | Test upload URL | Not required |
| AI Detection | `POST /api/v2/orders/ai-detection` | Test upload URL | Required |

Do not call a confirm endpoint for Watermark Embed or Watermark Extract. The request will fail because those services start after their uploads complete.

> [!WARNING]
>
> The Watermark v2 endpoints (`POST /api/v2/orders/wtr-embed` and `POST /api/v2/orders/wtr-extract`) ended support at 09:00 KST on October 9, 2026 (00:00 UTC). Migrate to the v3 endpoints (`/api/v3/orders/wtr-embed` and `/api/v3/orders/wtr-extract`). This guide describes the v3 endpoints for Watermark Embed and Watermark Extract.

## Choose a deterministic result

Use the input file name to exercise success and failure states without depending on an external processing service.

| File name suffix | Result |
| - | - |
| `*_fail.<ext>` | The order fails |
| `*_detected.<ext>` | Watermark Extract reports a detected watermark (`detectionStatus` is `detected`) |
| `*_undetected.<ext>` | Watermark Extract reports no watermark (`detectionStatus` is `undetected`) |
| `*_ai.<ext>` | AI Detection returns probability `0.98` |
| `*_human.<ext>` | AI Detection returns probability `0.02` |

Without a suffix, Anti-AI and Watermark Embed complete successfully, Watermark Extract reports no watermark, and AI Detection returns probability `0.02`. If any file in a multi-file order uses `_fail`, the order fails.

For Watermark Extract, only the name of the inspected file (`file.fileName`) selects `detected` or `undetected`. A `_detected` suffix on the original file has no effect, but `_fail` on either file fails the order.

## Test webhooks

Create an owned test webhook endpoint with the Dashboard, a live API key, or a test API key. A test key may omit `isTest` or set it to `true`; `isTest: false` returns `403 AUTH_FORBIDDEN`:

```bash theme={null}
curl -X POST https://api.bizmori.com/api/v2/orders/webhooks \
  -H "Authorization: Bearer $BIZMORI_TEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Integration test webhook",
    "url": "https://example.com/test-webhook",
    "isTest": true
  }'
```

* A test API key can create, list, get, update, and delete test endpoints owned by the same owner, list their events, and retry failed events. Live-mode and other-owner resources remain hidden.
* `isTest: true` endpoints receive test order events only.
* `isTest: false` endpoints receive live order events only.
* Test webhook payloads use the same event names, HMAC-SHA256 signature, and retry behavior as live webhooks.
* Anti-AI and Watermark Embed test events use `downloadUrl: null` because no result file is created.

See [Webhooks](https://docs.contentcare.ai/webhooks.md) for owner and mode isolation, signature verification, event payloads, and retry rules.

## Order details, downloads, and reports

After the uploads finish, a test order moves to `inProgress` and then to `complete` or `failed` about five seconds later. [Get order details (v3)](https://docs.contentcare.ai/api-reference/orders/get-order-v3.md) returns every test order, whether you created it with v2 or v3, in the same shape as a live order.

| Operation | Test API key behavior |
| - | - |
| `GET /api/v3/orders/{orderId}` | Returns the test order. While it is `pending`, `inputFiles[].uploadUrl` is a test upload URL. A Watermark Embed order has one item in `result.outputFiles` for each watermark text. `expiresAt` is seven days after the order was created. |
| `GET /api/v3/orders/{orderId}/download` | Completed Anti-AI and Watermark Embed test orders only. Returns `archiveUrl` and `files[]` that point to fixed sample files. `expiresInSeconds` follows the same rule as live orders (up to 3600 seconds). |
| `POST /api/v3/orders/{orderId}/reports`, `GET /api/v3/orders/{orderId}/reports/{locale}` | Watermark Extract orders with a `detected` result only. Returns `completed` and a sample report PDF URL that is valid for 300 seconds. |

* Download URLs point to fixed sample files, not to your output. `archiveUrl` is the sample file itself for a Watermark Embed order created with v3 that has one output, and a sample ZIP file otherwise. An Anti-AI test order without output files returns `files: []`.
* A detected result returns `watermarkText` as `MORI TEST WATERMARK`. `reportSupported` is `true` only for a Watermark Extract order created with v3 whose result is `detected`.
* The report is a one-page sample PDF. It does not contain your detection result, and the content does not change with `locale`.
* Report requests fail with `REPORT_NOT_AVAILABLE` for an `undetected` order, `ORDER_NOT_COMPLETED` for an order that is not complete or failed, and `ORDER_TYPE_NOT_MATCH` for a Watermark Embed order. Other owners' orders and live orders return `ORDER_NOT_FOUND`.

Differences from live Watermark orders:

* A test report request returns `200 completed` immediately. It never returns `202 queued` or `processing`, and it does not consume credits.
* `result.reports` in Get order details is always empty because test reports are not stored.
* Reusing an `idempotencyKey` returns the existing order without comparing the request body, so it never returns `409`.

## API behavior and limitations

| Operation | Test API key behavior |
| - | - |
| `GET /api/v2/orders` | Returns the account's persistent test orders |
| `GET /api/v2/orders/stats/recent` | Returns statistics for the account's test orders |
| `GET /api/v2/orders/{orderId}` | Deprecated. Returns a test order owned by the key's account |
| `POST /api/v2/orders/{orderId}/refresh-urls` | Refreshes an upload URL that has not been used yet |
| `GET /api/v2/orders/{orderId}/download` | Deprecated. Returns `404 PROCESSED_FILE_NOT_FOUND` |
| Webhook management and retries | Manage only test endpoints owned by the same owner; live-mode and other-owner IDs return `404`, while `isTest: false` returns `403 AUTH_FORBIDDEN` |

Test orders remain separate from live orders. A test key cannot read or modify live orders, and a live key cannot read or modify test orders.

Test API keys do not:

* run image or document processing;
* reserve or consume credits;
* create downloadable result files, except the fixed sample files returned by the Watermark download and report endpoints; or
* send events to live webhook endpoints.

For authentication details, see [Authentication](https://docs.contentcare.ai/authentication.md). For error handling, see [Error Codes](https://docs.contentcare.ai/errors.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.