Agentbookable Mandates API

User-authorization records for consequential actions

Operations 3

POST /booking-drafts Prepare a booking draft (the proposal shown to the user) #
POST /mandates Record the user's booking instruction (authorization) #
POST /mandates/for-draft Issue a consent-bound mandate for a draft #

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/agentbookable-com:agentbookable-com-mandates-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

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

agentbookable-com-mandates-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: AgentBookable — Booking API for AI agents Mandates API
  version: 3.0.0
  description: 'One booking interface for AI agents. Businesses keep their existing booking system and connect through AgentBookable (Composio-backed connectors such as Cal.com). Provider-specific identifiers are never exposed.


    ## Workflow


    1. Discover businesses: `GET /businesses`.

    2. Read capabilities on the business record.

    3. List services: `GET /businesses/{businessId}/services`.

    4. Check live availability: `POST /businesses/{businessId}/availability`.

    5. Prepare a draft: `POST /booking-drafts`.

    6. Obtain explicit user consent to that draft.

    7. Authorize: `POST /mandates/for-draft`.

    8. Book: `POST /bookings` with mandateRef + draftId.


    Example published business: `agentbookable-demo`.'
  contact:
    name: AgentBookable
    url: https://agentbookable.com
servers:
- url: https://agentbookable.com
tags:
- name: Mandates
  description: User-authorization records for consequential actions
paths:
  /booking-drafts:
    post:
      tags:
      - Mandates
      summary: Prepare a booking draft (the proposal shown to the user)
      description: Creates an immutable booking proposal with an opaque draft id. Validates live availability (the slot must be genuinely free now) and the service's customer requirements. Show this draft to the user as the final proposal before asking for consent.
      operationId: createBookingDraft
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DraftCreate'
      responses:
        '201':
          description: Draft created — show it to the user and obtain consent
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingDraft'
        '409':
          description: Slot no longer available
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: SLOT_NO_LONGER_AVAILABLE
                message: That appointment is no longer available.
                alternatives:
                - start: '2026-09-02T09:30:00+02:00'
                  end: '2026-09-02T10:00:00+02:00'
        '422':
          description: Missing required customer details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: MISSING_CUSTOMER_REQUIREMENT
                message: 'The business requires additional customer information before booking: phone. Ask the user for phone first.'
        '429':
          $ref: '#/components/responses/RateLimited'
  /mandates:
    post:
      tags:
      - Mandates
      summary: Record the user's booking instruction (authorization)
      description: Creates a short-lived, single-use mandate that authorizes ONE booking action for ONE business. The instruction must be the user's own words — agents must not fabricate it. Use the returned `mandateRef` in `POST /bookings` within 15 minutes. The mandate is consumed by the booking it authorizes.
      operationId: createMandate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MandateCreate'
            example:
              actorRef: assistant-claude-session-42
              action: create_booking
              businessId: ab_bus_c24850fce8cfb9db
              instruction: Book the 09:00 haircut on 1 September.
      responses:
        '200':
          description: Mandate created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MandateCreated'
              example:
                mandateRef: mandate_76a00b335de7bd57
                expiresAt: '2026-08-29T14:45:00.000Z'
        '400':
          description: Missing/invalid fields
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          $ref: '#/components/responses/RateLimited'
  /mandates/for-draft:
    post:
      tags:
      - Mandates
      summary: Issue a consent-bound mandate for a draft
      description: Assert that the user explicitly consented to the exact draft, and receive a single-use mandate bound to it. The consent assertion is audited (actorRef, method, draft hash). Any later change to the consequential booking details invalidates this authorization.
      operationId: createMandateForDraft
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConsentCreate'
            example:
              actorRef: assistant-session-42
              draftId: draft_abc123
              consent:
                consentObtained: true
                draftId: draft_abc123
                consentedBy: the customer
                consentMethod: 'chat reply: yes, book it'
                instruction: Yes, book it
      responses:
        '200':
          description: Mandate issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MandateCreated'
        '410':
          description: Draft expired — prepare a new draft
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: DRAFT_EXPIRED
                message: The booking draft has expired. Re-check availability, prepare a new draft, and obtain fresh consent.
        '422':
          description: CONSENT_REQUIRED — consent must be asserted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  schemas:
    BookingCreate:
      type: object
      required:
      - businessId
      - serviceId
      - customer
      - mandateRef
      properties:
        businessId:
          type: string
        serviceId:
          type: string
        slotId:
          type: string
          description: Slot id from the availability call (preferred)
        slot:
          type: object
          description: Explicit slot when you do not have a slotId
          properties:
            start:
              type: string
            end:
              type: string
            staffId:
              type: string
        customer:
          type: object
          required:
          - name
          properties:
            name:
              type: string
            email:
              type: string
              format: email
            phone:
              type: string
              description: Required when the service's bookingRequirements.phone is 'required'
            locale:
              type: string
            timezone:
              type: string
        mandateRef:
          type: string
          description: From POST /mandates — single-use, expires in 15 minutes
        idempotencyKey:
          type: string
          description: Stable key for safe retries
        draftId:
          type: string
          description: The consented draft (from POST /booking-drafts + POST /mandates/for-draft). Request must match the draft exactly.
    Requirement:
      type: object
      properties:
        id:
          type: string
          example: phone
        type:
          type: string
          enum:
          - text
          - email
          - phone
          - number
          - boolean
          - select
        label:
          type: string
        required:
          type: boolean
    BookingRequirements:
      type: object
      description: What the agent must collect from the user BEFORE booking. Contact requirements are provider-derived; AgentBookable never reveals which provider.
      properties:
        name:
          type: string
          enum:
          - required
          - optional
          description: Customer name.
        email:
          type: string
          enum:
          - required
          - optional
          description: Customer email.
        phone:
          type: string
          enum:
          - required
          - optional
          description: Customer phone. 'required' means the booking is rejected without one — collect it first.
        payment:
          type: boolean
          description: True when payment is required to confirm.
    ConsentCreate:
      type: object
      required:
      - actorRef
      - draftId
      - consent
      properties:
        actorRef:
          type: string
        draftId:
          type: string
        consent:
          type: object
          required:
          - consentObtained
          - draftId
          properties:
            consentObtained:
              type: boolean
              enum:
              - true
              description: Assert that the user explicitly consented to this exact draft after seeing the final details.
            draftId:
              type: string
              description: Must equal the draftId field
            consentedBy:
              type: string
            consentMethod:
              type: string
              description: 'e.g. ''chat reply: yes, book it'''
            instruction:
              type: string
              description: The user's exact consenting words (audit context)
    MandateCreate:
      type: object
      required:
      - actorRef
      - action
      - instruction
      properties:
        actorRef:
          type: string
          description: Stable identifier for who is acting on the user's behalf (e.g. your agent/session id). Used in the audit trail.
          example: assistant-session-42
        action:
          type: string
          enum:
          - create_booking
          - reschedule_booking
          - cancel_booking
        businessId:
          type: string
          description: Bind the mandate to this business. Strongly recommended; a bound mandate cannot be replayed elsewhere.
          example: ab_bus_c24850fce8cfb9db
        serviceId:
          type: string
          description: Optionally bind to a specific service.
        instruction:
          type: string
          description: The user's exact words. Do not paraphrase or invent. This is the consent evidence.
          example: Book the 09:00 haircut on 1 September.
    Error:
      type: object
      required:
      - error
      - message
      properties:
        error:
          type: string
          description: Fixed error-code vocabulary
          enum:
          - INVALID_REQUEST
          - AUTHENTICATION_FAILED
          - BUSINESS_NOT_FOUND
          - SERVICE_NOT_FOUND
          - SLOT_NO_LONGER_AVAILABLE
          - MANDATE_REQUIRED
          - MANDATE_INVALID
          - MANDATE_EXPIRED
          - MANDATE_ALREADY_USED
          - MANDATE_ACTION_MISMATCH
          - MANDATE_BUSINESS_MISMATCH
          - RATE_LIMITED
          - PROVIDER_ERROR
          - PROVIDER_UNAVAILABLE
        message:
          type: string
        requiredFields:
          type: array
          items:
            $ref: '#/components/schemas/Requirement'
          description: Present on 400 when customer details are missing
        alternatives:
          type: array
          items:
            type: object
          description: Present on 409 SLOT_NO_LONGER_AVAILABLE
    BookingDraft:
      type: object
      description: The proposal to show the user. Consequential fields are immutable; consent binds to this exact content (draftHash).
      properties:
        id:
          type: string
          example: draft_m1abc_def456
        businessId:
          type: string
        serviceId:
          type: string
        serviceName:
          type: string
          example: Haircut
        start:
          type: string
          example: '2026-09-02T09:00:00+02:00'
        end:
          type: string
          example: '2026-09-02T09:30:00+02:00'
        durationMinutes:
          type: integer
          example: 30
        timezone:
          type: string
          example: Europe/Paris
        staffId:
          type:
          - string
          - 'null'
        customer:
          $ref: '#/components/schemas/BookingCreate/properties/customer'
        requirements:
          $ref: '#/components/schemas/BookingRequirements'
        expiresAt:
          type: string
          description: Drafts expire after 30 minutes
    DraftCreate:
      type: object
      required:
      - businessId
      - serviceId
      - customer
      - actorRef
      properties:
        businessId:
          type: string
        serviceId:
          type: string
        slotId:
          type: string
          description: Slot id from the availability call (preferred)
        slot:
          type: object
          properties:
            start:
              type: string
            end:
              type: string
            staffId:
              type: string
        customer:
          $ref: '#/components/schemas/BookingCreate/properties/customer'
        actorRef:
          type: string
          description: Your agent/session identifier for the audit trail
    MandateCreated:
      type: object
      properties:
        mandateRef:
          type: string
          example: mandate_76a00b335de7bd57
        expiresAt:
          type: string
          description: The mandate is invalid after this time (15 minutes).
  responses:
    RateLimited:
      description: Too many requests — slow down
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: RATE_LIMITED
            message: Too many requests. Retry later.