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

# Test your request signature (B2B debug)

> Runs the exact same HMAC-SHA256 verification pipeline as the enforcing endpoints, but ALWAYS returns 200 with a field-by-field diagnostic instead of an opaque 401. Use it to validate your signing implementation before calling business endpoints: send any JSON body signed exactly as you would a real request, then compare `received_body` with the bytes you signed and recompute HMAC-SHA256 over `signed_payload_string` locally to compare against your own `v1`. For security the server does NOT return its computed signature. Never takes any business action regardless of payload. Rate-limited to 20 requests/minute per client.



## OpenAPI

````yaml /api-reference/openapi.json post /api/v3/debug/signature-check
openapi: 3.0.0
info:
  description: >-
    LauncX V3 API for integrators — create payments, run disbursements, and
    resolve bank payout destinations.
  title: LauncX API
  contact:
    name: LauncX Support
    email: support@launcx.com
  license:
    name: Proprietary
  version: '1.0'
servers:
  - url: https://live.launcx.com
    description: Production
  - url: https://v3.launcx.com
    description: Staging
security: []
paths:
  /api/v3/debug/signature-check:
    post:
      tags:
        - B2B - Debug
      summary: Test your request signature (B2B debug)
      description: >-
        Runs the exact same HMAC-SHA256 verification pipeline as the enforcing
        endpoints, but ALWAYS returns 200 with a field-by-field diagnostic
        instead of an opaque 401. Use it to validate your signing implementation
        before calling business endpoints: send any JSON body signed exactly as
        you would a real request, then compare `received_body` with the bytes
        you signed and recompute HMAC-SHA256 over `signed_payload_string`
        locally to compare against your own `v1`. For security the server does
        NOT return its computed signature. Never takes any business action
        regardless of payload. Rate-limited to 20 requests/minute per client.
      parameters:
        - name: x-api-key
          in: header
          description: Client API Key
          required: true
          schema:
            type: string
        - name: x-signature
          in: header
          description: >-
            The signature under test. Format: t=<ms>,v1=<hex>. Omitting it is
            allowed — the diagnostic will report missing_signature_header.
          required: false
          schema:
            type: string
      requestBody:
        description: Any JSON payload — hashed byte-for-byte, never parsed as business data
        required: false
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: Diagnostic result (returned for BOTH valid and invalid signatures)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignatureCheckResult'
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded (20 requests/minute)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    SignatureCheckResult:
      type: object
      properties:
        valid:
          type: boolean
          example: true
        diagnostics:
          $ref: '#/components/schemas/SignatureCheckDiagnostics'
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          example: invalid email or password
    SignatureCheckDiagnostics:
      type: object
      properties:
        received_body:
          description: >-
            The exact body bytes the server received — compare against what your
            code signed
          type: string
          example: '{"hello":"world"}'
        received_body_length:
          type: integer
          example: 17
        received_body_sha256:
          description: >-
            SHA-256 of the received body — quick byte-equality check against
            your side
          type: string
        received_timestamp:
          description: The t= value parsed from your x-signature header
          type: string
          example: '1719700000000'
        server_time_ms:
          type: integer
          example: 1719700000123
        window_delta_ms:
          description: >-
            Gap between your t and server time (only meaningful when the window
            check ran)
          type: integer
          example: 123
        window_ok:
          type: boolean
          example: true
        signed_payload_string:
          description: >-
            The exact string the server computed the HMAC over — recompute
            HMAC-SHA256 of this with your signing secret and compare with your
            v1
          type: string
          example: 1719700000000.{"hello":"world"}
        client_provided_signature:
          description: The v1= value parsed from your header, echoed back
          type: string
        diagnosis:
          description: >-
            One of: ok, signature_mismatch, hex_case_mismatch,
            timestamp_out_of_window, malformed_timestamp,
            missing_signature_header, malformed_signature_header,
            no_secret_provisioned, content_encoding_not_supported,
            body_too_large, read_body_failed, internal_error
          type: string
          example: ok

````