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

# Liveness + deepfake in one call

> Runs both checks on the same image. The overall `decision` is `real` only when every check passes its threshold; per-product outcomes are in `checks`. Costs 3 credits.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/unified_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/unified_detection:
    post:
      tags:
        - Detection
      summary: Liveness + deepfake in one call
      description: >-
        Runs both checks on the same image. The overall `decision` is `real`
        only when every check passes its threshold; per-product outcomes are in
        `checks`. Costs 3 credits.
      operationId: unifiedDetection
      requestBody:
        $ref: '#/components/requestBodies/DetectionInput'
      responses:
        '200':
          description: Scored checks
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnifiedResponse'
              example:
                product: unified
                decision: spoof
                checks:
                  face_liveness:
                    decision: real
                    genuine_score: 0.91
                    threshold: 0.5
                  deepfake:
                    decision: spoof
                    genuine_score: 0.31
                    threshold: 0.5
                latency_ms: 430
                credits_remaining: 1235
                session_id:
                  face_liveness: d2f8c1e4a90b4f0f8f1f2a3b4c5d6e7f
                  deepfake: a1b2c3d4e5f60718293a4b5c6d7e8f90
                request_id: 11223344556677889900aabbccddeeff
        '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.
      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
          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
        image/*:
          schema:
            type: string
            format: binary
            description: Raw image bytes as the request body.
  schemas:
    UnifiedResponse:
      type: object
      properties:
        product:
          type: string
          enum:
            - unified
        decision:
          type: string
          enum:
            - real
            - spoof
          description: '"real" only when every check passes its threshold.'
        checks:
          type: object
          description: Per-product outcome.
          properties:
            face_liveness:
              $ref: '#/components/schemas/Check'
            deepfake:
              $ref: '#/components/schemas/Check'
        latency_ms:
          type: integer
          description: Sum of per-model inference times.
        credits_remaining:
          type: integer
        session_id:
          type: object
          description: One logged detection session per product.
          additionalProperties:
            type: string
        request_id:
          type: string
    Check:
      type: object
      properties:
        decision:
          type: string
          enum:
            - real
            - spoof
        genuine_score:
          type: number
          description: >-
            Calibrated score in [0,1]; the decision boundary sits at 0.5 across
            model updates.
        threshold:
          type: number
          description: The threshold actually applied.
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
  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 · IMAGE_BACKLIT —
        user-fixable, never charged
      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.

````