> ## 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.

# Create watermark embed order

> Create an order that embeds invisible watermarks into images and PDFs.

- Up to 100 files per order, 1–10 watermark texts per file, 1–1,000 characters per text
- Each watermark text produces its own output file in `outputs[]` and uses 1 credit
- Supported extensions: `jpg`, `jpeg`, `png`, `webp`, `bmp`, `tif`, `tiff`, `pdf`. BMP must be uncompressed 24-bit RGB or 1- or 8-bit grayscale. TIFF must be single-page 8-bit RGB or 1- or 8-bit grayscale, without alpha
- A BMP or TIFF file outside that range (multi-page, 16-bit, palette, alpha, CMYK, and so on) fails the order with a public `errorCode`, and the credits are restored
- For each file without `originalFileUrl`, upload the file with `PUT` to `files[].uploadUrl` (valid for 900 seconds)
- Processing starts automatically when every file is uploaded. There is no confirm step
- Orders whose files are not uploaded within 12 hours become `failed`
- Poll [`GET /api/v3/orders/{orderId}`](/api-reference/orders/get-order-v3) until `status` is `complete`, then call the download endpoint




## OpenAPI

````yaml api-reference/openapi.yaml POST /api/v3/orders/wtr-embed
openapi: 3.0.0
info:
  title: BIZ MORI API
  version: 2.0.0
  description: >
    BIZ MORI API provides four core services for digital content protection:

    - **Anti-AI**: Protect images from AI training

    - **Watermark Embed**: Embed invisible digital watermarks into images

    - **Watermark Extract**: Extract and verify watermarks from images

    - **AI Detection**: Detect whether an image is AI-generated

    - **Test API keys**: Keys with the `sk_test_` prefix use the same Bearer
    authentication and support order-lifecycle testing with mock responses
    without running processing services or consuming credits; test uploads
    discard file contents and do not create result files
  contact:
    name: BIZ MORI Support
    email: support@bizmori.com
  license:
    name: Proprietary
    url: https://docs.bizmori.com/legal/terms
servers:
  - url: https://api.bizmori.com
    description: Production
security: []
tags:
  - name: Anti-AI
    description: Anti-AI image protection orders
  - name: Watermark Embed
    description: Watermark embedding orders
  - name: Watermark Extract
    description: Watermark extraction orders
  - name: AI Detection
    description: AI-generated image detection orders
  - name: Orders
    description: Order query and management
  - name: Webhooks
    description: Webhook configuration and events
  - name: Reports
    description: PDF analysis reports for watermark extract and AI Detection orders
paths:
  /api/v3/orders/wtr-embed:
    post:
      tags:
        - Watermark Embed
      summary: Create a watermark embed order
      description: >
        Create an order that embeds invisible watermarks into images and PDFs.


        - Up to 100 files per order, 1–10 watermark texts per file, 1–1,000
        characters per text

        - Each watermark text produces its own output file in `outputs[]` and
        uses 1 credit

        - Supported extensions: `jpg`, `jpeg`, `png`, `webp`, `bmp`, `tif`,
        `tiff`, `pdf`. BMP must be uncompressed 24-bit RGB or 1- or 8-bit
        grayscale. TIFF must be single-page 8-bit RGB or 1- or 8-bit grayscale,
        without alpha

        - A BMP or TIFF file outside that range (multi-page, 16-bit, palette,
        alpha, CMYK, and so on) fails the order with a public `errorCode`, and
        the credits are restored

        - For each file without `originalFileUrl`, upload the file with `PUT` to
        `files[].uploadUrl` (valid for 900 seconds)

        - Processing starts automatically when every file is uploaded. There is
        no confirm step

        - Orders whose files are not uploaded within 12 hours become `failed`

        - Poll [`GET
        /api/v3/orders/{orderId}`](/api-reference/orders/get-order-v3) until
        `status` is `complete`, then call the download endpoint
      operationId: createWatermarkV1EmbedOrder
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - idempotencyKey
                - files
              properties:
                idempotencyKey:
                  type: string
                  maxLength: 255
                  description: >-
                    Idempotency key. Use a new UUIDv4 for each new order and
                    reuse it only when retrying the same request. The same key
                    returns the existing order; the same key with a different
                    request body returns `409 WATERMARK_V2_CONFLICT`.
                files:
                  type: array
                  minItems: 1
                  maxItems: 100
                  description: Images and PDFs can be mixed in one order.
                  items:
                    type: object
                    required:
                      - fileName
                      - watermarks
                    properties:
                      fileName:
                        type: string
                        maxLength: 255
                        description: >-
                          File name with extension. Supported: `jpg`, `jpeg`,
                          `png`, `webp`, `bmp`, `tif`, `tiff`, `pdf`.
                      originalFileUrl:
                        type: string
                        format: uri
                        description: >-
                          Public HTTPS URL of the original file (optional). When
                          set, BIZ MORI downloads the file (up to 32 MiB,
                          redirects not followed) and no `uploadUrl` is issued
                          for it.
                      watermarks:
                        type: array
                        minItems: 1
                        maxItems: 10
                        description: >-
                          Watermark texts to embed. Each text produces a
                          separate output file and uses 1 credit.
                        items:
                          type: object
                          required:
                            - text
                          properties:
                            text:
                              type: string
                              minLength: 1
                              maxLength: 1000
            example:
              idempotencyKey: f47ac10b-58cc-4372-a567-0e02b2c3d479
              files:
                - fileName: campaign.png
                  watermarks:
                    - text: MORI-2026-001
                - fileName: contract.pdf
                  originalFileUrl: https://example.com/contract.pdf
                  watermarks:
                    - text: PARTNER-A
                    - text: PARTNER-B
      responses:
        '200':
          description: Order created, or the existing order for the same `idempotencyKey`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WatermarkV1OrderResponse'
              example:
                data:
                  orderId: '1234567890'
                  status: pending
                  processingDelayed: false
                  expiresAt: '2026-10-08T03:00:00.000Z'
                  files:
                    - fileId: '501'
                      uploadUrl: https://s3.ap-northeast-2.amazonaws.com/...
                    - fileId: '502'
                      uploadUrl: null
                  outputs:
                    - fileId: 501-1
                      inputFileId: '501'
                      outputIndex: 0
                      watermarkText: MORI-2026-001
                      status: pending
                      mediaKind: image
                    - fileId: 502-1
                      inputFileId: '502'
                      outputIndex: 0
                      watermarkText: PARTNER-A
                      status: pending
                      mediaKind: pdf
                    - fileId: 502-2
                      inputFileId: '502'
                      outputIndex: 1
                      watermarkText: PARTNER-B
                      status: pending
                      mediaKind: pdf
                  result: null
                  reports: []
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          description: The same `idempotencyKey` was used with a different request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: WATERMARK_V2_CONFLICT
        '429':
          description: Too many requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: RATE_LIMIT_EXCEEDED
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          description: Watermark processing is temporarily unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                code: WATERMARK_V2_UNAVAILABLE
      security:
        - BearerAuth: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |
            curl -X POST https://api.bizmori.com/api/v3/orders/wtr-embed \
              -H "Authorization: Bearer YOUR_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
              "idempotencyKey": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
              "files": [
                {
                  "fileName": "campaign.png",
                  "watermarks": [
                    {
                      "text": "MORI-2026-001"
                    }
                  ]
                },
                {
                  "fileName": "contract.pdf",
                  "originalFileUrl": "https://example.com/contract.pdf",
                  "watermarks": [
                    {
                      "text": "PARTNER-A"
                    },
                    {
                      "text": "PARTNER-B"
                    }
                  ]
                }
              ]
            }'
        - lang: javascript
          label: JavaScript
          source: >
            const response = await
            fetch(`https://api.bizmori.com/api/v3/orders/wtr-embed`, {
              method: 'POST',
              headers: {
                'Authorization': 'Bearer YOUR_API_KEY',
                'Content-Type': 'application/json'
              },
              body: JSON.stringify({
                "idempotencyKey": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
                "files": [
                  {
                    "fileName": "campaign.png",
                    "watermarks": [
                      {
                        "text": "MORI-2026-001"
                      }
                    ]
                  },
                  {
                    "fileName": "contract.pdf",
                    "originalFileUrl": "https://example.com/contract.pdf",
                    "watermarks": [
                      {
                        "text": "PARTNER-A"
                      },
                      {
                        "text": "PARTNER-B"
                      }
                    ]
                  }
                ]
              })
            });

            const { data } = await response.json();

            // PUT each file to its presigned URL (files[] follows the request
            order)

            // await fetch(data.files[0].uploadUrl, { method: 'PUT', body: file
            });
        - lang: python
          label: Python
          source: >
            import requests


            response = requests.post(
                f'https://api.bizmori.com/api/v3/orders/wtr-embed',
                headers={'Authorization': 'Bearer YOUR_API_KEY'},
                json={
                  "idempotencyKey": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
                  "files": [
                    {
                      "fileName": "campaign.png",
                      "watermarks": [
                        {
                          "text": "MORI-2026-001"
                        }
                      ]
                    },
                    {
                      "fileName": "contract.pdf",
                      "originalFileUrl": "https://example.com/contract.pdf",
                      "watermarks": [
                        {
                          "text": "PARTNER-A"
                        },
                        {
                          "text": "PARTNER-B"
                        }
                      ]
                    }
                  ]
                }
            )

            data = response.json()['data']

            # PUT each file to its presigned URL (files[] follows the request
            order)

            # requests.put(data['files'][0]['uploadUrl'],
            data=open('campaign.png', 'rb'))
components:
  schemas:
    WatermarkV1OrderResponse:
      type: object
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/WatermarkV1Order'
    ErrorResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
    WatermarkV1Order:
      type: object
      description: Invisible watermark order created with the v3 API
      required:
        - orderId
        - status
        - processingDelayed
        - files
        - outputs
        - result
        - reports
      properties:
        orderId:
          type: string
          description: Order ID
        status:
          type: string
          enum:
            - pending
            - inProgress
            - complete
            - failed
            - expired
          description: >
            Order processing status


            * `pending` - Waiting for file uploads

            * `inProgress` - Processing

            * `complete` - Processing finished. For extract orders, read the
            outcome from `result`

            * `failed` - Processing failed, or files were not uploaded within 12
            hours

            * `expired` - The retention period has ended and files were deleted
        processingDelayed:
          type: boolean
          description: >-
            `true` when automatic retries are exhausted and the order is waiting
            for manual recovery. The order stays `inProgress`
        expiresAt:
          type: string
          format: date-time
          nullable: true
          description: >-
            When the order files are deleted. Downloads and reports return
            `ORDER_EXPIRED` afterwards
        files:
          type: array
          description: >-
            Uploaded input files, in request order. Extract orders return the
            original first and the file to inspect second
          items:
            $ref: '#/components/schemas/WatermarkV1UploadFile'
        outputs:
          type: array
          description: >-
            Embed outputs. One entry per watermark text. Empty for extract
            orders
          items:
            $ref: '#/components/schemas/WatermarkV1Output'
        result:
          $ref: '#/components/schemas/WatermarkV1DetectionResult'
        reports:
          type: array
          description: Reports requested for this order
          items:
            type: object
            required:
              - locale
              - status
            properties:
              locale:
                type: string
                enum:
                  - ko-KR
                  - en-US
                  - ja-JP
              status:
                type: string
                enum:
                  - queued
                  - processing
                  - completed
                  - failed
    WatermarkV1UploadFile:
      type: object
      required:
        - fileId
        - uploadUrl
      properties:
        fileId:
          type: string
          description: Input file ID
        uploadUrl:
          type: string
          format: uri
          nullable: true
          description: >
            Presigned `PUT` URL for uploading the file, valid for 900 seconds.
            Issued only while the order `status` is `pending`, the retention
            period has not ended, and the file is waiting for upload.

            It is `null` for files given by `originalFileUrl`, files already
            uploaded, orders that became `failed` after the 12-hour upload
            window, and expired orders.
    WatermarkV1Output:
      type: object
      required:
        - fileId
        - inputFileId
        - outputIndex
        - watermarkText
        - status
        - mediaKind
      properties:
        fileId:
          type: string
          description: >-
            Output file ID in `{inputFileId}-{ordinal}` format, from
            `outputs[].fileId`
        inputFileId:
          type: string
          description: ID of the input file this output was created from
        outputIndex:
          type: integer
          minimum: 0
          description: Position of the watermark text within the input file's `watermarks`
        watermarkText:
          type: string
          description: The embedded watermark text
        status:
          type: string
          enum:
            - pending
            - queued
            - processing
            - completed
            - failed
            - retry_required
          description: Processing status of this output
        mediaKind:
          type: string
          enum:
            - image
            - pdf
    WatermarkV1DetectionResult:
      type: object
      nullable: true
      description: >-
        Extract result summary. `null` for embed orders and until the result is
        ready. Contains only the fields below
      required:
        - detectionStatus
        - reportSupported
        - watermarkText
      additionalProperties: false
      properties:
        detectionStatus:
          type: string
          enum:
            - detected
            - not_detected
            - inconclusive
            - unsupported
            - error
          description: >
            * `detected` - A watermark was found

            * `not_detected` - The file was fully checked and no watermark was
            found

            * `inconclusive` - A candidate was found but did not meet the
            confidence threshold

            * `unsupported` - The input cannot be processed (credit refunded)

            * `error` - Detection failed. This is not the same as no watermark
            (credit refunded)
        reportSupported:
          type: boolean
          description: >-
            Whether a report can be created from this result. `false` for images
            captured from a PDF
        watermarkText:
          type: string
          nullable: true
          description: >
            Embedded text of the detected watermark. Returned only when
            `detectionStatus` is `detected`, your account embedded the
            watermark, and exactly one issuance record matches.

            Otherwise `null`, for example when another account embedded the
            watermark.
  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: VALIDATION_FAILED
    Unauthorized:
      description: Authentication failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: AUTH_NOT_AUTHENTICATED
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            code: SERVER_INTERNAL_ERROR
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Bearer API key for external client access. Live keys use the `sk_`
        prefix; test keys use the `sk_test_` prefix and support order-lifecycle
        testing with mock responses without processing or credit usage.

````

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