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

> ## Agent Instructions
> OwnPay is licensed under AGPL-3.0 and is completely free - no licensing fees.
> Production docs URL: https://ownpay.org/docs - append .md to any page URL for clean markdown.
> OwnPay requires PHP 8.3+, MySQL/MariaDB, and Redis.
> MCP server available at https://ownpay.org/docs/mcp for programmatic documentation queries.
> Use root-relative links (e.g. /quickstart) for internal navigation - do NOT include /docs prefix.
> Plugin development: consult /developer/plugin-types/ pages for correct interfaces and manifests.

# Pair Mobile Companion Device

> Pairs a new physical mobile device running the companion app with a merchant brand profile.
Requires a valid numeric pairing code generated from the brand admin dashboard and a unique hardware device identifier.
On success, returns the encryption key (AES-256 key) used for local message storage, short-lived JWT access token, and long-lived refresh token.




## OpenAPI

````yaml /api/mobile_api.yaml post /api/mobile/v1/devices
openapi: 3.1.0
info:
  title: OwnPay Mobile Companion App API
  description: >
    The OwnPay Mobile API is exposed exclusively to the paired mobile companion
    application.

    It contains endpoints to complete initial device pairing, submit heartbeats
    to report online statuses, refresh authentication tokens, upload received
    SMS messages (supporting batch processing up to 200 items), fetch pending
    outbound SMS queues, acknowledge push notifications, and retrieve dashboard
    statistics.


    ### Security and Cryptography

    - Except for `/api/mobile/v1/devices` (bootstrap pairing) and
    `/api/mobile/v1/devices/token-refreshes` (token refresh), all endpoints
    require authentication using a JSON Web Token (JWT) in the HTTP
    `Authorization` header.
      ```http
      Authorization: Bearer <jwt_access_token>
      ```
    - Device fingerprints are checked during token refreshes.

    - Endpoints are brand-scoped; data visibility is restricted to the specific
    brand/merchant.
  version: 1.0.0
servers:
  - url: https://{brand_domain}
    description: Master brand domain hosting OwnPay gateway.
    variables:
      brand_domain:
        default: ownpay.org
        description: The domain of the specific white-labeled gateway.
security:
  - JWTAuth: []
paths:
  /api/mobile/v1/devices:
    post:
      summary: Pair Mobile Companion Device
      description: >
        Pairs a new physical mobile device running the companion app with a
        merchant brand profile.

        Requires a valid numeric pairing code generated from the brand admin
        dashboard and a unique hardware device identifier.

        On success, returns the encryption key (AES-256 key) used for local
        message storage, short-lived JWT access token, and long-lived refresh
        token.
      operationId: pairMobileDevice
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PairDeviceRequest'
      responses:
        '201':
          description: Device paired and registered successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PairDeviceResponse'
        '400':
          description: Pairing failed due to an invalid/expired pairing code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiSingleErrorResponse'
        '422':
          description: Validation error. Both pairing_code and device_id are required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiSingleErrorResponse'
      security: []
components:
  schemas:
    PairDeviceRequest:
      type: object
      required:
        - pairing_code
        - device_id
      properties:
        pairing_code:
          type: string
          description: >-
            The 6-digit numeric pairing code displayed on the merchant settings
            dashboard.
          example: '482931'
        device_id:
          type: string
          description: Hardware identifier unique to the companion device.
          example: '358291039201921'
        device_name:
          type: string
          default: Unknown
          example: Samsung SM-G991B
        app_version:
          type: string
          default: 1.0.0
          example: v1.2.4
        platform:
          type: string
          default: android
          enum:
            - android
            - ios
          example: android
    PairDeviceResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            access_token:
              type: string
              description: Short-lived access token (JWT) valid for 24 hours.
              example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
            device_uuid:
              type: string
              format: uuid
              description: Unique system identifier assigned to the paired device.
              example: b810d1c8-bc1e-4df1-b2f4-83b9c9d2b2f4
            refresh_token:
              type: string
              description: Long-lived refresh token (JWT) valid for 30 days.
              example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.refresh...
            aes_key:
              type: string
              description: >-
                Base64-encoded AES-256 key utilized to sign or encrypt data
                locally.
              example: YTI4MzkxOGQyNzM4MTk4MmFjOTIzYjg5...
            expires_in:
              type: integer
              description: Expiration duration of the access token in seconds.
              example: 86400
    ApiSingleErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          example: Invalid pairing code
        errors:
          type: array
          items:
            type: object
            properties:
              code:
                type: string
                example: INVALID_PAIRING_CODE
              message:
                type: string
                example: Invalid pairing code
              field:
                type: string
                nullable: true
                example: null
        request_id:
          type: string
          example: 8f5a2e9b0c7d4e5f
  securitySchemes:
    JWTAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Enter your Short-lived access JWT token.

````

## Related topics

- [List Paired Companion Devices](/docs/api-reference/list-paired-companion-devices.md)
- [Revoke Paired Device](/docs/api-reference/revoke-paired-device.md)
- [List Companion App Notifications](/docs/api-reference/list-companion-app-notifications.md)
- [Retrieve Device Connection Status](/docs/api-reference/retrieve-device-connection-status.md)
- [System Health Check](/docs/api-reference/system-health-check.md)
