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

# Recognize a challenge

> For clients that operate their own browser. Supply image data and the challenge instruction, then receive the answer directly; there is no solve token or polling. The API key must have Recognition API permission. Successful answers cost $0.00030; unsupported challenges or missing answers are not charged. Images may be base64 (optionally a data URI) or, for hCaptcha-hosted images only, HTTPS URLs. Each image is limited to 1.5 MiB and 1 megapixel; total image pixels are limited to 12 megapixels and the JSON request body to 12 MiB.

Submit a challenge instruction and images for recognition. Successfully answered requests are charged.


## OpenAPI

````yaml https://ninetile.io/openapi.json POST /recognize
openapi: 3.1.0
info:
  title: Ninetile API
  version: 1.0.0
  description: >-
    Native Ninetile JSON API. Solve hCaptcha challenges, retrieve solve status,
    report token outcomes, inspect account usage, and recognize hCaptcha image
    challenges. Successful solves and recognitions are charged to the account's
    prepaid USD balance.
servers:
  - url: https://api.ninetile.io/v1
    description: Primary API
  - url: https://api.radiumstore.org/v1
    description: Alternate API host
security:
  - BearerAuth: []
  - ApiKeyHeader: []
tags:
  - name: Solves
    description: Create, inspect, cancel, and report hCaptcha token solves.
  - name: Feedback
    description: Report verdicts for completed solves.
  - name: Account
    description: Inspect account balance, limits, and daily usage.
  - name: Recognition
    description: Recognize hCaptcha image challenges for clients running their own browser.
  - name: Status
    description: Public service liveness.
paths:
  /recognize:
    post:
      tags:
        - Recognition
      summary: Recognize an hCaptcha image challenge
      description: >-
        For clients that operate their own browser. Supply image data and the
        challenge instruction, then receive the answer directly; there is no
        solve token or polling. The API key must have Recognition API
        permission. Successful answers cost $0.00030; unsupported challenges or
        missing answers are not charged. Images may be base64 (optionally a data
        URI) or, for hCaptcha-hosted images only, HTTPS URLs. Each image is
        limited to 1.5 MiB and 1 megapixel; total image pixels are limited to 12
        megapixels and the JSON request body to 12 MiB.
      operationId: recognizeImages
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecognitionRequest'
            examples:
              grid:
                summary: Select matching tiles
                value:
                  type: hcaptcha
                  task: Select all bicycles
                  image_data:
                    - >-
                      iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==
              areaSelect:
                summary: Click a point in an image
                value:
                  type: hcaptcha_area_select
                  task: Click the cat
                  image_data:
                    - >-
                      iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==
              fullDrag:
                summary: Full challenge object for a drag challenge
                value:
                  data:
                    request_type: image_drag_drop
                    requester_question:
                      en: Drag the letter
                    tasklist:
                      - task_key: k1
                        datapoint_uri: >-
                          iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==
                        entities:
                          - entity_id: e1
                            entity_uri: >-
                              iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==
                            coords:
                              - 1
                              - 1
                            size:
                              - 1
                              - 1
      responses:
        '200':
          description: Answer returned and charged.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecognitionResponse'
              examples:
                grid:
                  value:
                    id: rec_01ARZ3NDEKTSV4RRFFQ69G5FAV
                    data:
                      - true
                      - false
                      - false
                    charged_usd: 0.0003
                areaSelect:
                  value:
                    id: rec_01ARZ3NDEKTSV4RRFFQ69G5FAV
                    data:
                      x: 40
                      'y': 45
                      w: 0
                      h: 0
                    points:
                      - x: 40
                        'y': 45
                    charged_usd: 0.0003
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/RecognitionFailed'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  schemas:
    RecognitionRequest:
      anyOf:
        - $ref: '#/components/schemas/RecognitionGridRequest'
        - $ref: '#/components/schemas/RecognitionAreaRequest'
        - $ref: '#/components/schemas/FullRecognitionRequest'
    RecognitionResponse:
      type: object
      required:
        - id
        - data
        - charged_usd
      properties:
        id:
          type: string
          pattern: ^rec_
        data:
          description: >-
            For grid tasks, booleans per tile (nested by page for full challenge
            objects); for area select, a point box or boxes; for drag
            challenges, backend answer objects.
          anyOf:
            - $ref: '#/components/schemas/GridAnswer'
            - $ref: '#/components/schemas/AreaAnswer'
            - type: array
              items:
                $ref: '#/components/schemas/AreaAnswer'
            - type: array
              items:
                type: array
                items:
                  type: boolean
            - type: array
              items:
                type: object
            - type: array
              items:
                type: array
                items:
                  type: object
        points:
          description: >-
            Area-select click points in percent; present only for area-select
            answers.
          anyOf:
            - type: array
              items:
                $ref: '#/components/schemas/Point'
            - type: array
              items:
                type: array
                items:
                  $ref: '#/components/schemas/Point'
        charged_usd:
          type: number
          description: Charge for a successful recognition (default $0.00030).
    RecognitionGridRequest:
      type: object
      required:
        - type
        - task
      properties:
        type:
          const: hcaptcha
        task:
          type: string
          minLength: 1
          maxLength: 500
        image_data:
          type: array
          minItems: 1
          maxItems: 27
          items:
            $ref: '#/components/schemas/ImageSource'
        image_urls:
          type: array
          minItems: 1
          maxItems: 27
          items:
            type: string
            format: uri
            description: HTTPS URL hosted on hcaptcha.com.
        image_examples:
          type: array
          minItems: 1
          maxItems: 3
          items:
            $ref: '#/components/schemas/ImageSource'
      anyOf:
        - required:
            - image_data
          properties:
            image_data:
              type: array
              minItems: 1
              maxItems: 27
              items:
                $ref: '#/components/schemas/ImageSource'
        - required:
            - image_urls
          properties:
            image_urls:
              type: array
              minItems: 1
              maxItems: 27
              items:
                type: string
                format: uri
                description: HTTPS URL hosted on hcaptcha.com.
    RecognitionAreaRequest:
      type: object
      required:
        - type
        - task
      properties:
        type:
          const: hcaptcha_area_select
        task:
          type: string
          minLength: 1
          maxLength: 500
        image_data:
          type: array
          minItems: 1
          maxItems: 1
          items:
            $ref: '#/components/schemas/ImageSource'
        image_urls:
          type: array
          minItems: 1
          maxItems: 1
          items:
            type: string
            format: uri
            description: HTTPS URL hosted on hcaptcha.com.
        image_examples:
          type: array
          minItems: 1
          maxItems: 3
          items:
            $ref: '#/components/schemas/ImageSource'
      anyOf:
        - required:
            - image_data
          properties:
            image_data:
              type: array
              minItems: 1
              maxItems: 1
              items:
                $ref: '#/components/schemas/ImageSource'
        - required:
            - image_urls
          properties:
            image_urls:
              type: array
              minItems: 1
              maxItems: 1
              items:
                type: string
                format: uri
                description: HTTPS URL hosted on hcaptcha.com.
    FullRecognitionRequest:
      type: object
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/FullChallenge'
    GridAnswer:
      type: array
      items:
        type: boolean
    AreaAnswer:
      type: object
      required:
        - x
        - 'y'
        - w
        - h
      properties:
        x:
          type: number
          minimum: 0
          maximum: 100
        'y':
          type: number
          minimum: 0
          maximum: 100
        w:
          type: number
          minimum: 0
          maximum: 100
        h:
          type: number
          minimum: 0
          maximum: 100
    Point:
      type: object
      required:
        - x
        - 'y'
      properties:
        x:
          type: number
          minimum: 0
          maximum: 100
        'y':
          type: number
          minimum: 0
          maximum: 100
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - param
            - request_id
          properties:
            code:
              type: string
              enum:
                - invalid_request
                - unauthorized
                - insufficient_credits
                - key_credit_limit_exceeded
                - account_locked
                - forbidden
                - not_eligible
                - not_found
                - conflict
                - payload_too_large
                - unsupported_media_type
                - expired_window
                - recognition_failed
                - validation_error
                - concurrency_limit_exceeded
                - proxy_unavailable
                - rate_capped
                - rate_limited
                - sitekey_rate_limited
                - internal_error
                - maintenance
                - capacity_exhausted
                - proxy_pool_depleted
            message:
              type: string
            param:
              type:
                - string
                - 'null'
            request_id:
              type: string
              format: uuid
    ImageSource:
      type: string
      description: >-
        Base64-encoded PNG, JPEG, WebP, or GIF, optionally prefixed by a
        matching `data:image/...;base64,` URI, or an HTTPS URL on an
        hcaptcha.com host.
    FullChallenge:
      oneOf:
        - type: object
          required:
            - request_type
            - requester_question
            - tasklist
          properties:
            request_type:
              const: image_label_binary
            requester_question:
              type: object
              required:
                - en
              properties:
                en:
                  type: string
                  minLength: 1
                  maxLength: 500
              unevaluatedProperties: true
            requester_question_example:
              oneOf:
                - $ref: '#/components/schemas/ImageSource'
                - type: array
                  minItems: 1
                  maxItems: 3
                  items:
                    $ref: '#/components/schemas/ImageSource'
            tasklist:
              type: array
              minItems: 1
              maxItems: 27
              items:
                $ref: '#/components/schemas/FullTask'
          unevaluatedProperties: true
        - type: object
          required:
            - request_type
            - requester_question
            - tasklist
          properties:
            request_type:
              const: image_label_area_select
            requester_question:
              type: object
              required:
                - en
              properties:
                en:
                  type: string
                  minLength: 1
                  maxLength: 500
              unevaluatedProperties: true
            requester_question_example:
              oneOf:
                - $ref: '#/components/schemas/ImageSource'
                - type: array
                  minItems: 1
                  maxItems: 3
                  items:
                    $ref: '#/components/schemas/ImageSource'
            tasklist:
              type: array
              minItems: 1
              maxItems: 5
              items:
                $ref: '#/components/schemas/FullTask'
          unevaluatedProperties: true
        - type: object
          required:
            - request_type
            - requester_question
            - tasklist
          properties:
            request_type:
              const: image_drag_drop
            requester_question:
              type: object
              required:
                - en
              properties:
                en:
                  type: string
                  minLength: 1
                  maxLength: 500
              unevaluatedProperties: true
            requester_question_example:
              oneOf:
                - $ref: '#/components/schemas/ImageSource'
                - type: array
                  minItems: 1
                  maxItems: 3
                  items:
                    $ref: '#/components/schemas/ImageSource'
            tasklist:
              type: array
              minItems: 1
              maxItems: 5
              items:
                $ref: '#/components/schemas/FullDragTask'
          unevaluatedProperties: true
      description: >-
        Other challenge properties are passed through to the recognition
        backend. Image limits apply to datapoint, entity, and example images
        combined.
      unevaluatedProperties: true
    FullTask:
      type: object
      required:
        - task_key
        - datapoint_uri
      properties:
        task_key:
          type: string
          minLength: 1
        datapoint_uri:
          $ref: '#/components/schemas/ImageSource'
      unevaluatedProperties: true
    FullDragTask:
      type: object
      required:
        - task_key
        - datapoint_uri
        - entities
      properties:
        task_key:
          type: string
          minLength: 1
        datapoint_uri:
          $ref: '#/components/schemas/ImageSource'
        entities:
          type: array
          items:
            $ref: '#/components/schemas/FullEntity'
      description: Additional task fields are passed through to the recognition backend.
      unevaluatedProperties: true
    FullEntity:
      type: object
      required:
        - entity_uri
      properties:
        entity_uri:
          $ref: '#/components/schemas/ImageSource'
      description: Additional entity fields are passed through to the recognition backend.
      unevaluatedProperties: true
  headers:
    RequestId:
      description: Request identifier for support inquiries.
      schema:
        type: string
        format: uuid
    RetryAfter:
      description: >-
        Seconds to wait before retrying; present when the error asks the client
        to wait.
      schema:
        type: integer
        minimum: 1
  responses:
    BadRequest:
      description: Invalid JSON or a non-object request body (`invalid_request`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: API key missing, malformed, unknown, or revoked (`unauthorized`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    PaymentRequired:
      description: >-
        Insufficient account balance or key spend limit (`insufficient_credits`,
        `key_credit_limit_exceeded`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: >-
        Account locked or key not permitted to access this endpoint
        (`account_locked`, `forbidden`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    PayloadTooLarge:
      description: >-
        Request body exceeds 12 MiB or an image exceeds 1.5 MiB
        (`payload_too_large`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    UnsupportedMediaType:
      description: Request body must use JSON content type (`unsupported_media_type`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RecognitionFailed:
      description: Challenge is unsupported or no answer was found (`recognition_failed`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: >-
        Request, concurrency, sitekey, or authentication-attempt limit reached
        (`rate_limited`, `concurrency_limit_exceeded`, `rate_capped`,
        `sitekey_rate_limited`, `proxy_unavailable`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalError:
      description: Unexpected server error (`internal_error`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ServiceUnavailable:
      description: >-
        Solver or recognition service is not ready or at capacity
        (`maintenance`, `capacity_exhausted`, `proxy_pool_depleted`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Ninetile API key, sent as `Authorization: Bearer <key>`. Keys are issued
        in the dashboard.
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
      description: Alternative to the Authorization Bearer header.

````

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