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

# Search consents

> Searches contact-grain consent observations for the credential's scope, ordered by `created_at` (newest first). Filters combine with AND. Email and SMS consents for the same guest are separate rows. The API returns individual observations; when multiple rows exist for the same contact×purpose within a property group, effective eligibility is the most restrictive status among them. Paginated via `limit`/`cursor`. Requires scope `read:consents`.




## OpenAPI

````yaml /api-reference/openapi.yaml get /v1/consents
openapi: 3.1.0
info:
  title: Casa API
  version: 1.0.0
  description: >
    Headless, read-only access to the guest context layer — the entire canonical
    data model over HTTP.


    Every endpoint is **scoped by the credential**: the default scope is the
    caller's property group, returning data across all of its properties. Auth
    sources resolve to the same credential: a user-generated **API key**
    (`casa_…`, created in Account settings — the recommended method for
    machines), a WorkOS AuthKit session JWT (the web app; org and role come from
    verified token claims), or a static token. (The MCP server also accepts
    read-only OAuth connector tokens, but those are rejected on these REST
    routes.) Send `X-Property-Id` to drill down into a single property; API keys
    can also be pinned to one property at creation. Tenant isolation holds by
    construction.


    Integration-management endpoints write connection *metadata* only and are
    session-only; canonical guest data enters exclusively through the connector
    workers and the ingest pipeline.


    The Model Context Protocol (MCP) server is exposed separately at `/mcp` and
    is documented under **MCP Server** in the guides — it is not a REST endpoint
    and is intentionally omitted from this reference. It accepts the same API
    keys.
servers:
  - url: https://api.casa-layer.com
    description: Production Cloudflare Worker
security:
  - bearerAuth: []
tags:
  - name: System
    description: Liveness, health, and the public welcome page.
  - name: Guests
    description: Canonical guest profiles as ingested from each source system.
  - name: Master Profiles
    description: >-
      Identity-resolved golden records — one entity per real guest, merged
      across sources and properties.
  - name: Reservations
    description: >-
      Reservation records linked to guest profiles, searchable by status, stay
      window, and channel.
  - name: Transactions
    description: >-
      Revenue lines (Pace Transactions V2–shaped) linked to guests and
      optionally reservations.
  - name: Consents
    description: >
      Contact-grain consent observations (contact method + value × purpose).
      Rows store decisive signals only (granted/withdrawn/denied); absence of a
      row means unknown / not eligible. Effective eligibility within a property
      group is the most restrictive status among stored observations for the
      same contact×purpose (withdrawn/denied beat granted).
  - name: Tables
    description: >
      Attio-style ops tables — curated or filter-defined containers for
      day-to-day work inside Casa. Tables are not consent eligibility records
      and not marketing segments; campaign audiences stay in downstream ESP
      tools (Klaviyo, Mailchimp, and peers).
  - name: Actions
    description: Guest actions (purchases, visits, and other tracked events).
  - name: Events
    description: >-
      The append-only guest event log — full change history or latest delta
      slice per entity.
  - name: Reviews
    description: Guest reviews with free-text search and an aggregate summary.
  - name: Loyalty
    description: Loyalty programs and member search (tier, points, guest).
  - name: Dimensions
    description: Reference dimensions — booking channels and bookable spaces.
  - name: Properties
    description: >-
      Properties within a group, plus self-serve onboarding (org-anchored tenant
      bootstrap).
  - name: SQL
    description: >-
      Read-only SQL over the public data model, isolated per tenant by row-level
      security.
  - name: API Keys
    description: Manage the organization's API keys (session-only).
  - name: Integrations
    description: >-
      Connection metadata for source systems (Mews, Square, …). Metadata only —
      never canonical guest data. Session-only.
paths:
  /v1/consents:
    get:
      tags:
        - Consents
      summary: Search consents
      description: >
        Searches contact-grain consent observations for the credential's scope,
        ordered by `created_at` (newest first). Filters combine with AND. Email
        and SMS consents for the same guest are separate rows. The API returns
        individual observations; when multiple rows exist for the same
        contact×purpose within a property group, effective eligibility is the
        most restrictive status among them. Paginated via `limit`/`cursor`.
        Requires scope `read:consents`.
      parameters:
        - name: contact_value
          in: query
          description: >-
            Exact match on normalized contact value (e.g. email address or E.164
            phone).
          schema:
            type: string
        - name: contact_method
          in: query
          schema:
            type: string
            enum:
              - email
              - sms
              - phone
              - postal
              - whatsapp
              - unknown
        - name: purpose
          in: query
          schema:
            type: string
            enum:
              - marketing
              - marketing_partner
              - transactional
              - payment_storage
              - biometric_capture
              - other
        - name: status
          in: query
          schema:
            type: string
            enum:
              - granted
              - denied
              - withdrawn
        - name: integration_id
          in: query
          schema:
            type: string
            format: uuid
        - name: guest_profile_id
          in: query
          description: >-
            Filter to observations linked to this guest profile at ingest time
            (provenance only).
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/PropertyHeader'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: Matching consent observations.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - data
                    properties:
                      data:
                        type: array
                        items:
                          $ref: '#/components/schemas/Consent'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
components:
  parameters:
    PropertyHeader:
      name: X-Property-Id
      in: header
      required: false
      description: >
        Optional single-property drill-down. When set, narrows the request to
        this property; it must belong to the caller's group, else `403`. A
        property-pinned API key is already narrowed and ignores this header.
      schema:
        type: string
        format: uuid
    Limit:
      name: limit
      in: query
      required: false
      description: >
        Page size — rows returned per call (1–500). This is NOT a cap on the
        total dataset: follow `next_cursor` to retrieve every matching row.
      schema:
        type: integer
        minimum: 1
        maximum: 500
        default: 100
    Cursor:
      name: cursor
      in: query
      required: false
      description: >
        Opaque pagination token from a previous response's `next_cursor`. Omit
        for the first page. A malformed token returns `400 invalid_cursor`.
      schema:
        type: string
  schemas:
    Pagination:
      type: object
      description: >
        Keyset-pagination fields present on every list/search response. When
        `has_more` is true, re-request with `cursor` set to `next_cursor`;
        repeat until `next_cursor` is null to retrieve the full result set.
      required:
        - next_cursor
        - has_more
      properties:
        next_cursor:
          type:
            - string
            - 'null'
          description: Opaque cursor for the next page, or null on the last page.
        has_more:
          type: boolean
          description: Whether another page exists.
    Consent:
      type: object
      description: >
        A contact-grain consent observation from a source system. Subject is
        contact method + value and purpose; `guest_profile_id` is ingest-time
        provenance only.
      required:
        - id
        - property_id
        - property_group_id
        - integration_id
        - source_id
        - source_version
        - contact_method
        - contact_value
        - status
        - purpose
        - source_field
        - observed_at
        - source_payload
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
        property_id:
          type: string
          format: uuid
        property_group_id:
          type: string
          format: uuid
        integration_id:
          type: string
          format: uuid
        guest_profile_id:
          type:
            - string
            - 'null'
          format: uuid
          description: >-
            Guest profile linked when the observation was ingested (provenance
            only).
        source_id:
          type: string
          description: Stable id from the source system.
        source_version:
          type: string
          description: Monotonic source version (bigint serialized as a string).
        contact_method:
          type: string
          enum:
            - email
            - sms
            - phone
            - postal
            - whatsapp
            - unknown
        contact_value:
          type: string
          description: >-
            Normalized contact identifier (e.g. lowercased email or E.164
            phone).
        status:
          type: string
          enum:
            - granted
            - denied
            - withdrawn
        purpose:
          type: string
          enum:
            - marketing
            - marketing_partner
            - transactional
            - payment_storage
            - biometric_capture
            - other
        source_field:
          type: string
          description: Vendor field or path this observation was mapped from.
        source_updated_at:
          type:
            - string
            - 'null'
          format: date-time
        observed_at:
          type: string
          format: date-time
        source_payload:
          type: object
          additionalProperties: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Machine-readable error code.
        scope:
          type: string
          description: The scope that was required
          when the error is a scope failure.: null
        detail:
          type: string
          description: Optional human-readable detail.
  responses:
    BadRequest:
      description: >-
        Malformed request — e.g. a `cursor` that is not a valid pagination
        token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: invalid_cursor
    Unauthorized:
      description: Missing, unknown, or revoked bearer credential.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: unauthorized
    Forbidden:
      description: >
        The credential lacks the scope required for this endpoint, or the auth
        surface is wrong. Machine-readable codes include `forbidden` (scope or
        role), `tenant_not_provisioned` (org claim present but no property
        group), and `mcp_oauth_required` (SPA session token used on `/mcp`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: forbidden
            scope: read:guests
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        `Authorization: Bearer <token>`. Token types resolve to the same scoped
        credential: a user-generated **API key** (`casa_…`, from Account
        settings — recommended for machines and MCP clients), a WorkOS AuthKit
        session JWT (the web app; org and role come from verified token claims),
        or a static token. API keys are group-scoped, optionally pinned to one
        property at creation. MCP OAuth connector tokens authenticate the MCP
        server only and are rejected on these REST routes.

````