cQnce Agents – Self API

Agent self-service routes (requires agent JWT)

GitHub OpenAPI

Operations 16

GET /v1/agents/me Get own profile #
PATCH /v1/agents/me Update own profile #
DELETE /v1/agents/me Delete own account #
GET /v1/agents/me/invites List own invites #
POST /v1/agents/me/invites/{inviteId}/accept Accept tenant invite #
POST /v1/agents/me/invites/{inviteId}/decline Decline tenant invite #
GET /v1/agents/me/requests List requests for agent #
POST /v1/agents/me/requests/{id}/challenge Issue a strong-auth challenge #
POST /v1/agents/me/requests/{id}/respond Respond to a request #
DELETE /v1/agents/me/tenants/{tenantId} Leave a network #
POST /v1/agents/me/heartbeat Send heartbeat #
PATCH /v1/agents/me/avatar Update avatar #
DELETE /v1/agents/me/avatar Delete avatar #
GET /v1/agents/me/stats Get own response stats #
GET /v1/agents/me/requests/{id} Get request detail (agent) #
GET /v1/agents/me/requests/{id}/attachments/{index} Get request attachment (agent) #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/cqnce-app:cqnce-app-agents-self-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

cqnce-app-agents-self-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: cQnce Agents – Self API
  description: 'Authorization-request routing and agent-management API for the cQnce platform.


    ## Authentication


    | Scheme | Header | Used by |

    |---|---|---|

    | Bearer JWT (tenant) | `Authorization: Bearer ` | Dashboard / admin routes |

    | Bearer JWT (agent) | `Authorization: Bearer ` | Agent mobile app routes |

    | API Key | `x-api-key: ` | Server-to-server request submission |'
  version: 1.0.0
  contact:
    name: cQnce Support
servers:
- url: https://api.cqnce.app
  description: Production
tags:
- name: Agents – Self
  description: Agent self-service routes (requires agent JWT)
paths:
  /v1/agents/me:
    get:
      tags:
      - Agents – Self
      summary: Get own profile
      description: Returns the authenticated agent's profile including pending invites and assigned projects.
      operationId: getAgentMe
      security:
      - agentJWT: []
      responses:
        '200':
          description: Agent profile
          content:
            application/json:
              schema:
                type: object
                properties:
                  agent:
                    $ref: '#/components/schemas/Agent'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Agent not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    patch:
      tags:
      - Agents – Self
      summary: Update own profile
      operationId: patchAgentMe
      security:
      - agentJWT: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                surname:
                  type: string
                email:
                  type: string
                  format: email
                fcmToken:
                  type: string
                  description: Firebase Cloud Messaging token for push notifications
                online:
                  type: boolean
      responses:
        '200':
          description: Profile updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  agent:
                    $ref: '#/components/schemas/Agent'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    delete:
      tags:
      - Agents – Self
      summary: Delete own account
      operationId: deleteAgentMe
      security:
      - agentJWT: []
      responses:
        '200':
          description: Account deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/invites:
    get:
      tags:
      - Agents – Self
      summary: List own invites
      description: Returns the agent's invites, optionally filtered by status.
      operationId: listAgentMeInvites
      security:
      - agentJWT: []
      parameters:
      - name: status
        in: query
        schema:
          type: string
          enum:
          - PENDING
          - ACCEPTED
          - DECLINED
        description: Filter by invite status
      responses:
        '200':
          description: List of invites
          content:
            application/json:
              schema:
                type: object
                properties:
                  invites:
                    type: array
                    items:
                      $ref: '#/components/schemas/AgentInvite'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/invites/{inviteId}/accept:
    post:
      tags:
      - Agents – Self
      summary: Accept tenant invite
      operationId: agentAcceptInvite
      security:
      - agentJWT: []
      parameters:
      - name: inviteId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Invite accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Invite not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/invites/{inviteId}/decline:
    post:
      tags:
      - Agents – Self
      summary: Decline tenant invite
      operationId: agentDeclineInvite
      security:
      - agentJWT: []
      parameters:
      - name: inviteId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Invite declined
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Invite not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/requests:
    get:
      tags:
      - Agents – Self
      summary: List requests for agent
      description: 'Returns authorization requests relevant to the authenticated agent.


        - `status=PENDING` (default): requests pending the agent''s decision

        - `status=HISTORY`: requests the agent has already responded to'
      operationId: getAgentRequests
      security:
      - agentJWT: []
      parameters:
      - name: status
        in: query
        schema:
          type: string
          enum:
          - PENDING
          - HISTORY
        description: Filter by status
      - name: limit
        in: query
        schema:
          type: integer
          default: 50
          maximum: 100
      - name: offset
        in: query
        schema:
          type: integer
          default: 0
      responses:
        '200':
          description: Paginated list of requests
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/PaginationMeta'
                - type: object
                  properties:
                    requests:
                      type: array
                      items:
                        $ref: '#/components/schemas/AuthRequest'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/requests/{id}/challenge:
    post:
      tags:
      - Agents – Self
      summary: Issue a strong-auth challenge
      description: 'Issues a server-generated one-time nonce (challenge) bound to the specified request,

        the authenticated agent, and the agent''s registered device. The agent must sign the nonce with

        its device private key (ECDSA P-256 / SHA-256) and submit the resulting `challengeProof` together

        with `challengeId` when calling `POST /v1/agents/me/requests/{id}/respond`. The server then

        verifies the signature against the registered device public key, making `strongAuthUsed`

        server-verified rather than client-trusted.


        **Challenge lifecycle:**

        1. Agent calls this endpoint → receives `{ challengeId, nonce, expiresAt }`

        2. Agent signs the nonce locally (device private key, ECDSA P-256 + SHA-256) → `challengeProof` (Base64)

        3. Agent submits the response including `challengeId` and `challengeProof`

        4. Server verifies the signature, marks the challenge as used (one-time), sets `strongAuthUsed = true`


        **Error codes:**

        - `409` – Agent has no registered device key (challenge flow requires a device public key)

        - `409` – Request is already resolved

        - `404` – Request not found'
      operationId: issueStrongAuthChallenge
      security:
      - agentJWT: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Request ID
      responses:
        '201':
          description: Challenge issued
          content:
            application/json:
              schema:
                type: object
                properties:
                  challengeId:
                    type: string
                    format: uuid
                    description: Opaque challenge identifier to pass back in the respond call
                  nonce:
                    type: string
                    description: Base64url-encoded random nonce (32 bytes) to sign with the device private key
                  expiresAt:
                    type: string
                    format: date-time
                    description: UTC timestamp after which the challenge is no longer valid (2-minute TTL)
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Request not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: No registered device key or request is already resolved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/requests/{id}/respond:
    post:
      tags:
      - Agents – Self
      summary: Respond to a request
      description: 'Submit an approval or rejection decision for a pending authorization request.


        **Strong-auth challenge flow (required for strong auth):**

        Strong auth is credited only when it is cryptographically proven. Call

        `POST /v1/agents/me/requests/{id}/challenge` to obtain a `{ challengeId, nonce }`, sign the

        nonce with the device private key (ECDSA P-256 + SHA-256), then include `challengeId` and

        `challengeProof` (Base64 signature) in this request body. When the proof verifies, the server

        sets `strongAuthUsed = true`.


        A `strongAuthUsed` flag sent without a valid proof is **not** credited: it is recorded as

        `false`, and a request whose routing rule has `requireStrongAuth` is rejected with `403`.


        **Error codes for challenge validation:**

        - `404` – `challengeId` not found

        - `403` – Challenge belongs to a different agent or request, or device mismatch

        - `403` – Challenge proof signature is invalid

        - `409` – Challenge has already been used (replay attempt rejected)

        - `410` – Challenge has expired'
      operationId: agentRespondToRequest
      security:
      - agentJWT: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Request ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - decision
              properties:
                decision:
                  type: string
                  enum:
                  - APPROVED
                  - REJECTED
                reason:
                  type: string
                  description: Optional reason for the decision. Required for REJECTED when the matched routing rule has rejectReasonRequired=true.
                strongAuthUsed:
                  type: boolean
                  description: 'Client-reported biometric/strong auth. Not evidence on its own: it is credited only when accompanied by a valid challengeId/challengeProof, and recorded as false otherwise. Supply the challenge proof to have strong auth counted.'
                challengeId:
                  type: string
                  format: uuid
                  description: ID of a challenge previously issued by POST /v1/agents/me/requests/{id}/challenge. Required together with challengeProof to enable server-verified strong auth.
                challengeProof:
                  type: string
                  description: Base64-encoded ECDSA P-256 / SHA-256 signature over the challenge nonce, produced by the device private key. Required together with challengeId.
      responses:
        '200':
          description: Decision recorded
          content:
            application/json:
              schema:
                type: object
                properties:
                  response:
                    $ref: '#/components/schemas/AgentResponse'
                  requestStatus:
                    type: string
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Agent not assigned to project, strong auth required, or challenge proof invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Request or challenge not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Already responded, request not pending, or challenge already used (replay)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '410':
          description: Challenge has expired
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/tenants/{tenantId}:
    delete:
      tags:
      - Agents – Self
      summary: Leave a network
      description: Removes the authenticated agent from the specified tenant network.
      operationId: agentLeaveTenant
      security:
      - agentJWT: []
      parameters:
      - name: tenantId
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Tenant ID to leave
      responses:
        '200':
          description: Agent removed from network
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Agent is not a member of this network
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/heartbeat:
    post:
      tags:
      - Agents – Self
      summary: Send heartbeat
      description: Updates the agent's `lastHeartbeatAt` timestamp. Should be called periodically to keep the agent marked as active for push-fallback suppression.
      operationId: agentHeartbeat
      security:
      - agentJWT: []
      responses:
        '200':
          description: Heartbeat recorded
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    example: true
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/avatar:
    patch:
      tags:
      - Agents – Self
      summary: Update avatar
      description: Uploads a base64-encoded image as the agent's avatar (max ~270 KB).
      operationId: patchAgentMeAvatar
      security:
      - agentJWT: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - avatarUrl
              properties:
                avatarUrl:
                  type: string
                  description: Base64 data URL (data:image/...) up to ~270 KB
      responses:
        '200':
          description: Avatar updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  agent:
                    $ref: '#/components/schemas/Agent'
        '400':
          description: Validation error or file too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    delete:
      tags:
      - Agents – Self
      summary: Delete avatar
      description: Removes the agent's avatar.
      operationId: deleteAgentMeAvatar
      security:
      - agentJWT: []
      responses:
        '200':
          description: Avatar removed
          content:
            application/json:
              schema:
                type: object
                properties:
                  agent:
                    $ref: '#/components/schemas/Agent'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/stats:
    get:
      tags:
      - Agents – Self
      summary: Get own response stats
      description: Returns approval/rejection statistics for the authenticated agent.
      operationId: getAgentMeStats
      security:
      - agentJWT: []
      responses:
        '200':
          description: Agent stats
          content:
            application/json:
              schema:
                type: object
                properties:
                  totalApproved:
                    type: integer
                  totalRejected:
                    type: integer
                  totalResponded:
                    type: integer
                  todayApproved:
                    type: integer
                  todayRejected:
                    type: integer
                  last7Days:
                    type: array
                    items:
                      type: object
                      properties:
                        date:
                          type: string
                          format: date
                        approved:
                          type: integer
                        rejected:
                          type: integer
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/requests/{id}:
    get:
      tags:
      - Agents – Self
      summary: Get request detail (agent)
      description: Returns a single authorization request with attachment URLs refreshed for preview/download.
      operationId: getAgentMeRequest
      security:
      - agentJWT: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Request ID
      responses:
        '200':
          description: Request detail with refreshed attachment URLs
          content:
            application/json:
              schema:
                type: object
                properties:
                  request:
                    $ref: '#/components/schemas/AuthRequest'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Agent not assigned to this request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Request not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/agents/me/requests/{id}/attachments/{index}:
    get:
      tags:
      - Agents – Self
      summary: Get request attachment (agent)
      description: Redirects to a signed attachment URL or returns a base64-encoded payload for inline rendering.
      operationId: getAgentMeRequestAttachment
      security:
      - agentJWT: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Request ID
      - name: index
        in: path
        required: true
        schema:
          type: integer
          minimum: 0
        description: Attachment index
      responses:
        '200':
          description: Attachment content (base64 for inline attachments)
        '302':
          description: Redirect to signed attachment URL
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Agent not assigned to this request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Request or attachment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    AuthRequest:
      type: object
      properties:
        id:
          type: string
          format: uuid
        projectId:
          type: string
          format: uuid
        payload:
          type: object
          description: Arbitrary payload submitted with the request
        metadata:
          type:
          - object
          - 'null'
        attachments:
          type:
          - array
          - 'null'
          description: Optional list of attachments (images or documents) sent with the request
          items:
            type: object
            required:
            - name
            properties:
              name:
                type: string
                description: Display name of the attachment
              mimeType:
                type: string
                example: image/jpeg
                description: MIME type of the attachment content
              url:
                type: string
                format: uri
                description: Public URL to the attachment (mutually exclusive with data)
              data:
                type: string
                description: Base64-encoded attachment content (mutually exclusive with url)
        status:
          type: string
          enum:
          - PENDING
          - APPROVED
          - REJECTED
          - EXPIRED
          - CANCELLED
        routingMode:
          type: string
          enum:
          - PARALLEL
          - SERIAL
          - MAJORITY
          - CHAIN
        rejectReasonRequired:
          type: boolean
        rejectReasonOptions:
          type: array
          items:
            type: string
        defaultRejectReason:
          type:
          - string
          - 'null'
        callbackUrl:
          type:
          - string
          - 'null'
          format: uri
        wsClientId:
          type:
          - string
          - 'null'
        createdAt:
          type: string
          format: date-time
        resolvedAt:
          type:
          - string
          - 'null'
          format: date-time
    AgentResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        requestId:
          type: string
          format: uuid
        agentId:
          type: string
          format: uuid
        agent:
          type:
          - object
          - 'null'
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
        decision:
          type: string
          enum:
          - APPROVED
          - REJECTED
        reason:
          type:
          - string
          - 'null'
        respondedAt:
          type: string
          format: date-time
        deviceId:
          type:
          - string
          - 'null'
          format: uuid
          description: Device that signed this response (null for legacy unsigned responses)
        signature:
          type:
          - string
          - 'null'
          description: Base64-encoded ECDSA P-256 signature over "requestId:decision[:reason]"
        strongAuthUsed:
          type: boolean
          description: Whether the agent confirmed biometric/strong authentication before submitting this response
    Error:
      type: object
      properties:
        error:
          type: string
          example: Validation failed
        details:
          type: array
          items:
            type: object
    AgentInvite:
      type: object
      properties:
        id:
          type: string
          format: uuid
        phone:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        email:
          type:
          - string
          - 'null'
          format: email
        status:
          type: string
          enum:
          - PENDING
          - ACCEPTED
          - DECLINED
        tenantId:
          type: string
          format: uuid
        agentId:
          type:
          - string
          - 'null'
          format: uuid
        createdAt:
          type: string
          format: date-time
    PaginationMeta:
      type: object
      properties:
        total:
          type: integer
        limit:
          type: integer
        offset:
          type: integer
    Agent:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        surname:
          type:
          - string
          - 'null'
        email:
          type:
          - string
          - 'null'
          format: email
        phone:
          type: string
        online:
          type: boolean
        tenantId:
          type:
          - string
          - 'null'
          format: uuid
        createdAt:
          type: string
          format: date-time
  securitySchemes:
    tenantJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT issued on tenant login (`POST /v1/auth/login`)
    agentJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT issued on agent login/register (`POST /v1/auth/agent/login` or `/register`)
    projectApiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Per-project API key used for server-to-server request submission