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

# Bootstrap an incoming voice call

> Called by the HiDesk telephony platform when a call arrives on an anny Phone number.

anny resolves the dialed number to an organization, builds the agent configuration for the call, and returns:

- the agent `default_language` and full `instructions` (system prompt),
- the MCP `tools` (server definitions, allowlists, signed call-context headers) the agent may use during the conversation,
- the anny-internal `call_session_id` that must be echoed back in the post-call webhook.

### Authentication

The request body is signed by HiDesk with HMAC-SHA256 using the shared secret configured during onboarding. The hex-encoded digest is sent in the `X-Anny-Signature` header.

anny verifies the signature against the **raw** request body before any JSON parsing. If verification fails the response is `401 Unauthorized`.

### Tool headers

Each entry in `tools[].headers` already contains everything HiDesk needs to call the MCP server on the agent's behalf:

| Header | Description |
|---|---|
| `X-Call-Context-Payload` | Base64-encoded call context (organization, call session, caller metadata) — signed by anny |
| `X-Call-Context-Signature` | HMAC-SHA256 signature of the payload — signed by anny |
| `X-Tenant-ID` | anny organization external ID, required by every MCP request |
| `Mcp-Session-Id` | UUID identifying this MCP session — keep stable for the duration of the call |

Forward `tools[].headers` verbatim on every MCP request. Do not strip, reorder, or mutate them — the signature is computed over the exact `X-Call-Context-Payload` value.




## OpenAPI

````yaml /developers/openapi/admin-internal.openapi.json post /api/voice/incoming-call
openapi: 3.1.0
info:
  title: admin-api
  version: '1.0'
  description: >-
    The Admin API gives you **full programmatic access** to your anny
    organization. It is built for **server-side integrations** — backend
    services, automation scripts, and custom tooling that act on behalf of your
    team.


    ---


    ## When to use the Admin API


    Use the Admin API when you need to **drive workflows from your own
    systems**:


    - **Sync membership data** — create or update customers, assign them to
    communities, reflect subscription status from an external CRM

    - **Create bookings programmatically** — build back-office tools or automate
    repeat reservations without going through the customer checkout

    - **Issue and forward invoices** — generate invoices, send them to
    customers, or push them to your accounting system

    - **React to real-time events** — pair the API with
    [Webhooks](/developers/guides/admin/webhooks) to trigger side effects
    whenever a booking is created, cancelled, or checked in

    - **Drive display panels** — push live occupancy and schedule data to
    digital signage or lobby displays


    Combined with [webhook subscriptions](/developers/guides/admin/webhooks),
    you can build fully automated, event-driven workflows without polling.


    ---


    ## Authentication


    Generate a long-lived API token directly in the admin dashboard under
    **Organization Settings → API**. All requests require it in the
    `Authorization` header:


    ```

    Authorization: Bearer {access_token}

    ```


    Every endpoint is **organization-scoped**. Pass your organization ID as a
    query parameter on every request:


    ```

    ?o={organization_id}

    ```


    See the [Authentication guide](/developers/guides/authentication) for token
    scopes and the full OAuth2 flow.


    ---


    ## Admin API vs Customer API


    | | Admin API | Customer API |

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

    | **Use case** | Server-side automation, backend tooling | End-user apps,
    booking widgets |

    | **Auth** | Required — API token or OAuth2 | Optional — many endpoints work
    without a token |

    | **Identifiers** | Immutable UUIDs and integer IDs | Slugs, booking
    numbers, order numbers |

    | **Access** | Full read/write | Public and customer-owned data only |


    → [Go to the Customer API](/developers/api-reference/customer)


    ---


    ## Resource Identifiers


    The Admin API uses **immutable IDs** — UUIDs for most entities, integers for
    legacy ones. These are safe to store in external systems and never change,
    even if an organization renames a resource.


    ---


    ## Starting Points


    | Guide | What it covers |

    |---|---|

    | [Getting Started](/developers) | First steps and quickstart |

    | [JSON:API Conventions](/developers/guides/json-api-conventions) | Request
    and response format |

    | [Authentication](/developers/guides/authentication) | API tokens, OAuth2,
    scopes |

    | [Availability & Booking Search](/developers/guides/availability) | Search
    open slots and timeslots |

    | [Admin Booking Creation](/developers/guides/admin/booking-creation) |
    Create bookings from the back office |

    | [Admin Booking Edit](/developers/guides/admin/booking-edit) | Edit
    resource, dates, fields, add-ons, and sub-bookings |

    | [Admin Booking Lifecycle](/developers/guides/admin/booking-lifecycle) |
    Status changes, check-in, cancellations |

    | [Invoices](/developers/guides/admin/invoices) | Create, send, and manage
    invoices |

    | [Customer Management](/developers/guides/admin/customer-management) |
    Create and manage customer records |

    | [Booking Calendars](/developers/guides/admin/calendar-events) | Custom
    calendar events |

    | [Timeslot Management](/developers/guides/admin/timeslot-management) |
    Manage timeslot CRUD, recurrence, allocations, and rescheduling |

    | [Broadcast Campaigns](/developers/guides/admin/broadcasting) | Email and
    push campaigns |

    | [Exports](/developers/guides/admin/exports) | Export bookings and customer
    data |

    | [Webhooks & Events](/developers/guides/admin/webhooks) | Subscribe to
    real-time events |


    ---


    ## Base URLs


    | Environment | URL |

    |---|---|

    | Production | `https://b.anny.co` |

    | Gov-Cloud | `https://b.anny.eu` |
  contact:
    name: anny GmbH
    url: https://anny.co
    email: support@anny.co
servers:
  - url: https://b.anny.co
    description: Production
  - url: https://b.anny.eu
    description: Gov-Cloud
security:
  - Bearer: []
tags:
  - name: Booking Quotas
  - name: Orders
  - name: Organizations
  - name: Table Configuration
  - name: Test-Results
  - name: User Settings
  - name: Terminal Locations
  - name: Terminal Readers
  - name: Connection Tokens
  - name: Views
  - name: Voice Integration
paths:
  /api/voice/incoming-call:
    post:
      tags:
        - Voice Integration
      summary: Bootstrap an incoming voice call
      description: >
        Called by the HiDesk telephony platform when a call arrives on an anny
        Phone number.


        anny resolves the dialed number to an organization, builds the agent
        configuration for the call, and returns:


        - the agent `default_language` and full `instructions` (system prompt),

        - the MCP `tools` (server definitions, allowlists, signed call-context
        headers) the agent may use during the conversation,

        - the anny-internal `call_session_id` that must be echoed back in the
        post-call webhook.


        ### Authentication


        The request body is signed by HiDesk with HMAC-SHA256 using the shared
        secret configured during onboarding. The hex-encoded digest is sent in
        the `X-Anny-Signature` header.


        anny verifies the signature against the **raw** request body before any
        JSON parsing. If verification fails the response is `401 Unauthorized`.


        ### Tool headers


        Each entry in `tools[].headers` already contains everything HiDesk needs
        to call the MCP server on the agent's behalf:


        | Header | Description |

        |---|---|

        | `X-Call-Context-Payload` | Base64-encoded call context (organization,
        call session, caller metadata) — signed by anny |

        | `X-Call-Context-Signature` | HMAC-SHA256 signature of the payload —
        signed by anny |

        | `X-Tenant-ID` | anny organization external ID, required by every MCP
        request |

        | `Mcp-Session-Id` | UUID identifying this MCP session — keep stable for
        the duration of the call |


        Forward `tools[].headers` verbatim on every MCP request. Do not strip,
        reorder, or mutate them — the signature is computed over the exact
        `X-Call-Context-Payload` value.
      operationId: post-voice-incoming-call
      parameters:
        - schema:
            type: string
            pattern: ^[A-Fa-f0-9]{64}$
          in: header
          name: X-Anny-Signature
          required: true
          description: >-
            Hex-encoded HMAC-SHA256 of the raw request body, computed with the
            shared HiDesk integration secret.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - called_number
                - provider_call_id
              properties:
                called_number:
                  type: string
                  pattern: ^\+[1-9]\d{4,14}$
                  description: >-
                    The anny Phone number that was dialed, in E.164 format (`+`
                    followed by 5–15 digits, leading digit non-zero).
                  example: '+4930123456789'
                caller_number:
                  type:
                    - string
                    - 'null'
                  maxLength: 30
                  description: >-
                    Caller's phone number. Send `null` when the caller withheld
                    their number.
                  example: '+4915112345678'
                caller_anonymous:
                  type: boolean
                  default: false
                  description: >-
                    Whether the caller withheld their number. When `true`,
                    `caller_number` must be `null`.
                channel:
                  type: string
                  enum:
                    - phone
                    - web
                    - native
                  default: phone
                  description: Originating channel for the call.
                provider_call_id:
                  type: string
                  maxLength: 255
                  description: >-
                    HiDesk's unique identifier for this call. anny uses this
                    value for deduplication against the post-call webhook.
                  example: hd_01HZ4T8K5W3N6R8VYJ7A2QXM9P
            examples:
              phone-call:
                summary: Standard inbound phone call
                value:
                  called_number: '+4930123456789'
                  caller_number: '+4915112345678'
                  caller_anonymous: false
                  channel: phone
                  provider_call_id: hd_01HZ4T8K5W3N6R8VYJ7A2QXM9P
              anonymous-call:
                summary: Caller withheld their number
                value:
                  called_number: '+4930123456789'
                  caller_number: null
                  caller_anonymous: true
                  channel: phone
                  provider_call_id: hd_01HZ4T8K5W3N6R8VYJ7A2QXM9P
      responses:
        '200':
          description: >-
            OK — agent configuration returned. HiDesk should start the AI
            conversation with these instructions and tools.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - default_language
                  - instructions
                  - tools
                  - call_session_id
                properties:
                  default_language:
                    type: string
                    description: >-
                      BCP-47 language tag the agent should open the call with.
                      Customers may switch language mid-call.
                    example: de
                  instructions:
                    type: string
                    description: >-
                      Full system prompt for the AI agent. Organization-specific
                      and built per call — do not cache across calls.
                  instructions_format:
                    type: string
                    enum:
                      - text
                      - markdown
                    default: text
                    description: Format hint for `instructions`. Currently always `text`.
                  tools:
                    type: array
                    description: >-
                      MCP server definitions the agent may use during the call.
                      Headers are pre-signed and call-scoped.
                    items:
                      type: object
                      additionalProperties: false
                      required:
                        - type
                        - server_label
                        - server_url
                        - headers
                        - require_approval
                        - allowed_tools
                      properties:
                        type:
                          type: string
                          enum:
                            - mcp
                          description: Tool transport type. Currently always `mcp`.
                        server_label:
                          type: string
                          description: >-
                            Human-readable label for this server (e.g. shown in
                            HiDesk's agent UI).
                          example: booking-management
                        server_url:
                          type: string
                          format: uri
                          description: Streamable HTTP MCP endpoint to connect to.
                          example: https://b.anny.co/mcp/customer
                        headers:
                          type: object
                          description: >-
                            Headers that must be sent on every MCP request to
                            `server_url`. Forward verbatim.
                          additionalProperties:
                            type: string
                          required:
                            - X-Call-Context-Payload
                            - X-Call-Context-Signature
                            - X-Tenant-ID
                            - Mcp-Session-Id
                          properties:
                            X-Call-Context-Payload:
                              type: string
                              description: >-
                                Base64-encoded call context payload — signed by
                                anny.
                            X-Call-Context-Signature:
                              type: string
                              description: >-
                                HMAC-SHA256 signature of
                                `X-Call-Context-Payload` — signed by anny.
                            X-Tenant-ID:
                              type: string
                              description: >-
                                anny organization external ID. Required by every
                                MCP request.
                            Mcp-Session-Id:
                              type: string
                              format: uuid
                              description: >-
                                UUID identifying this MCP session. Keep stable
                                for the duration of the call.
                        require_approval:
                          type: string
                          enum:
                            - never
                            - auto
                            - always
                          description: >-
                            Approval mode the agent should apply before invoking
                            tools on this server. `never` lets the agent invoke
                            any `allowed_tools` autonomously.
                        allowed_tools:
                          type: array
                          description: >-
                            Allowlist of MCP tool names the agent is permitted
                            to invoke on this server. Other tools returned by
                            `tools/list` MUST be ignored.
                          items:
                            type: string
                  call_session_id:
                    type: string
                    format: uuid
                    description: >-
                      anny-internal session ID. **Must** be echoed back as
                      `call_session_id` in the post-call webhook so anny can
                      correlate metadata and recording with the conversation
                      state.
                    example: 7c3e2f1a-4d8b-4e2c-9f5a-1b6d8e0c2a47
              examples:
                default:
                  value:
                    default_language: de
                    instructions: >-
                      You are the AI receptionist for Glow & Co. Greet the
                      caller in German. Use the booking-management MCP tools to
                      look up availability and create bookings…
                    instructions_format: text
                    tools:
                      - type: mcp
                        server_label: booking-management
                        server_url: https://b.anny.co/mcp/customer
                        require_approval: never
                        allowed_tools:
                          - get_organization
                          - list_services
                          - get_availability_intervals
                          - add_booking
                          - send_booking_link
                        headers:
                          X-Call-Context-Payload: >-
                            eyJvcmciOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJjYWxsX3Nlc3Npb24iOiI3YzNlMmYxYS00ZDhiLTRlMmMtOWY1YS0xYjZkOGUwYzJhNDcifQ==
                          X-Call-Context-Signature: >-
                            3f9b8c4e1d2a6f5b7c8e9d0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c
                          X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000
                          Mcp-Session-Id: 8a1f2b3c-4d5e-6f70-8192-a3b4c5d6e7f8
                    call_session_id: 7c3e2f1a-4d8b-4e2c-9f5a-1b6d8e0c2a47
        '401':
          description: >-
            Unauthorized — `X-Anny-Signature` is missing or does not match an
            HMAC-SHA256 of the raw request body.
        '404':
          description: >-
            Not Found — `called_number` is not provisioned for any organization
            on anny.
        '422':
          description: >-
            Validation error — one or more fields failed validation (see request
            body schema).
      security:
        - AnnySignature: []
components:
  securitySchemes:
    Bearer:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.anny.co/oauth/authorize
          tokenUrl: https://auth.anny.co/oauth/token
          refreshUrl: https://auth.anny.co/oauth/token/refresh
          scopes: {}
    AnnySignature:
      type: apiKey
      in: header
      name: X-Anny-Signature
      description: >
        HMAC-SHA256 signature of the raw request body, computed with the shared
        HiDesk integration secret and sent as a lowercase hex string.


        Verified by anny before JSON parsing. Mismatch → `401 Unauthorized`.

````