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

# Face liveness check

> Checks whether the face in the image is a live capture rather than a presentation attack (printed photo, screen replay, mask). Costs 1 credit.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/liveness_detection
openapi: 3.1.0
info:
  title: SpoofSense API
  version: '1.0'
  description: >-
    Face liveness and deepfake detection. All errors use the envelope `{"error":
    {"code", "message"}}`. Input errors (4xx) are never charged.
servers:
  - url: https://api.spoofsense.ai
security:
  - secretKey: []
tags:
  - name: Detection
    description: >-
      Stateless checks on an image you already have. Authenticate with your
      secret key.
  - name: Verification sessions
    description: >-
      The secure capture flow used by the SDKs and hosted page. Server-side
      calls use the secret key; client-side calls use the session's sst_ token.
  - name: Service
paths:
  /v1/liveness_detection:
    post:
      tags:
        - Detection
      summary: Face liveness check
      description: >-
        Checks whether the face in the image is a live capture rather than a
        presentation attack (printed photo, screen replay, mask). Costs 1
        credit.
      operationId: livenessDetection
      requestBody:
        $ref: '#/components/requestBodies/DetectionInput'
      responses:
        '200':
          description: Scored check
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DetectionResponse'
              example:
                product: face_liveness
                decision: real
                genuine_score: 0.9333
                threshold: 0.5
                spoof_type: null
                latency_ms: 190
                credits_remaining: 1240
                session_id: d2f8c1e4a90b4f0f8f1f2a3b4c5d6e7f
                request_id: 9b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '413':
          $ref: '#/components/responses/ImageTooLarge'
        '422':
          $ref: '#/components/responses/Unprocessable'
        '502':
          $ref: '#/components/responses/Upstream'
components:
  requestBodies:
    DetectionInput:
      required: true
      description: >-
        The image, in any supported form. Max 10 MB. EXIF orientation is applied
        automatically. The detected face's bounding box must be at least 224×224
        pixels, or the call returns 422 FACE_TOO_SMALL — pass `min_face_check:
        false` to skip that gate.
      content:
        application/json:
          schema:
            type: object
            properties:
              data:
                type: string
                description: 'Base64-encoded image, or a full data URL. Alias: `image`.'
              image_url:
                type: string
                format: uri
                description: >-
                  http(s) URL we fetch server-side (10 s timeout). Alias: `url`.
                  Provide either `data` or `image_url`.
              threshold:
                type: number
                minimum: 0
                maximum: 1
                description: >-
                  Optional per-request decision threshold. Defaults to your org
                  setting (0.5 unless changed).
              thresholds:
                type: object
                description: >-
                  Unified only: per-product thresholds, e.g. {"face_liveness":
                  0.6, "deepfake": 0.4}.
                additionalProperties:
                  type: number
                  minimum: 0
                  maximum: 1
              min_face_check:
                type: boolean
                default: true
                description: >-
                  Set to false to disable the 224×224 minimum-face-size gate
                  (422 FACE_TOO_SMALL) for this request. Small faces are
                  upscaled before scoring, so accuracy degrades on faces well
                  under 224 px — use only if your capture flow can't guarantee
                  close-up faces. A face must still be detectable.
          example:
            data: /9j/4AAQSkZJRg…
            threshold: 0.5
        multipart/form-data:
          schema:
            type: object
            required:
              - file
            properties:
              file:
                type: string
                format: binary
                description: 'The image file. Alias field name: `image`.'
              threshold:
                type: number
                minimum: 0
                maximum: 1
              min_face_check:
                type: boolean
                default: true
                description: >-
                  "false" disables the 224×224 minimum-face-size gate for this
                  request.
        image/*:
          schema:
            type: string
            format: binary
            description: Raw image bytes as the request body.
  schemas:
    DetectionResponse:
      type: object
      properties:
        product:
          type: string
          enum:
            - face_liveness
            - deepfake
        decision:
          type: string
          enum:
            - real
            - spoof
          description: genuine_score > threshold
        genuine_score:
          type: number
          description: Calibrated score in [0,1].
        threshold:
          type: number
          description: >-
            The threshold actually applied (request override, org setting, or
            0.5).
        spoof_type:
          type:
            - string
            - 'null'
          description: Always null for current models.
        latency_ms:
          type: integer
          description: Model inference time.
        credits_remaining:
          type: integer
          description: Balance after this call.
        session_id:
          type: string
          description: Id of the logged detection session (visible in the console).
        request_id:
          type: string
          description: Quote this when contacting support.
        signals:
          allOf:
            - $ref: '#/components/schemas/DeepfakeSignals'
          description: 'Deepfake only: what each of the two detectors found.'
    DeepfakeSignals:
      type: object
      description: >-
        What each deepfake check found. Content Credentials (C2PA) are checked
        first; a valid credential saying the image is AI-made decides alone and
        the two model signals come back with status "skipped". The image is
        "real" only if every signal that ran is real; the top-level
        genuine_score is the lowest signal score, and one threshold applies to
        all of them.
      properties:
        content_credentials:
          type: object
          description: >-
            C2PA Content Credentials embedded in the file, checked before the
            models.
          properties:
            decision:
              type:
                - string
                - 'null'
              enum:
                - spoof
                - null
              description: >-
                "spoof" when a valid credential says AI-generated or AI-edited;
                otherwise null. Never "real".
            genuine_score:
              type:
                - number
                - 'null'
              description: 0 when decisive, otherwise null.
            status:
              type: string
              enum:
                - ai_generated
                - ai_edited
                - no_ai_claim
                - invalid
                - not_found
            generator:
              type: string
              description: >-
                Tool named in the credential. Only when the signer is on the
                C2PA trust list.
            signed_by:
              type: string
              description: >-
                Signing organisation. Only when the signer is on the C2PA trust
                list.
          required:
            - decision
            - genuine_score
            - status
        ai_generated:
          description: >-
            Whole-image check for AI-generated or AI-edited content. Runs on
            every image, with or without a face.
          allOf:
            - $ref: '#/components/schemas/DeepfakeSignal'
            - type: object
              properties:
                status:
                  type: string
                  enum:
                    - skipped
                  description: >-
                    Present only when Content Credentials decided and the model
                    didn't run.
                kind:
                  type: string
                  enum:
                    - generated
                    - edited
                  description: >-
                    Present only when this signal flags the image: made from
                    scratch by AI, or a real photo edited with AI. A hint, not a
                    forensic finding.
        face_manipulation:
          description: >-
            Face swaps, AI face edits, lip-sync and reenactment, judged on the
            largest face.
          allOf:
            - $ref: '#/components/schemas/DeepfakeSignal'
            - type: object
              properties:
                status:
                  type: string
                  enum:
                    - checked
                    - no_face
                    - face_too_small
                    - skipped
                  description: >-
                    Whether the face check ran. face_too_small = the largest
                    face is under 64 px; skipped = Content Credentials decided.
                face_box:
                  type: array
                  items:
                    type: integer
                  minItems: 4
                  maxItems: 4
                  description: >-
                    [x, y, w, h] of the judged face, in pixels of the image as
                    sent (no EXIF rotation). Absent when no face was found.
              required:
                - status
      required:
        - ai_generated
        - face_manipulation
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
    DeepfakeSignal:
      type: object
      properties:
        decision:
          type:
            - string
            - 'null'
          enum:
            - real
            - spoof
            - null
          description: >-
            This signal at the applied threshold. null when the signal didn't
            run.
        genuine_score:
          type:
            - number
            - 'null'
          description: >-
            Calibrated like the top-level genuine_score (0.5 boundary). null
            when the signal didn't run.
      required:
        - decision
        - genuine_score
  responses:
    BadRequest:
      description: BAD_REQUEST · INVALID_THRESHOLD · NONCE_MISMATCH
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: BAD_REQUEST
              message: Provide 'data' (base64) or 'image_url'
    Unauthorized:
      description: UNAUTHORIZED — missing, invalid, or revoked API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: UNAUTHORIZED
              message: Missing, invalid, or revoked API key
    InsufficientCredits:
      description: INSUFFICIENT_CREDITS — top up in the console
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INSUFFICIENT_CREDITS
              message: Insufficient credits
    ImageTooLarge:
      description: IMAGE_TOO_LARGE — over 10 MB
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: IMAGE_TOO_LARGE
              message: Image too large (max 10 MB)
    Unprocessable:
      description: >-
        INVALID_IMAGE · FACE_NOT_DETECTED · FACE_TOO_SMALL (face bounding box
        under 224×224 px) · IMAGE_BACKLIT — user-fixable, never charged. The
        face errors come from liveness.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: FACE_NOT_DETECTED
              message: No face found in the image
    Upstream:
      description: UPSTREAM_ERROR — inference service unavailable; retry with backoff
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: UPSTREAM_ERROR
              message: Inference service unavailable
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      description: >-
        Your secret key (sk_live_…), server-side only. Also accepted as an
        `x-api-key` header.

````

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