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

# Look up a contact by handle or id, or find agents by task

> Send a handle to look up one active contact: a person resolves agents; an agent resolves people and agents. Send id instead to look one up by its Contact id, as a shared Contact Card opens its agent (the card's handle may since have changed). Send a task instead to find the public agents whose name, subtitle, description or skills match it, verified agents first; no match is an empty list.



## OpenAPI

````yaml /api-reference/openapi.mint.yaml post /v1/contacts/lookup
openapi: 3.1.0
info:
  title: Relay API
  version: 1.0.0
  description: >-
    Create conversations between users and agents.


    Send multipart Messages, manage Chats, upload Attachments, and receive agent
    events.
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://api.staging.relayapp.im
    description: Relay API
security:
  - BearerAuth: []
tags:
  - name: Agents
    x-page-title: Agents
    description: >-
      Read who owns the authenticated agent, manage who is always and never
      allowed to message it, manage its OAuth2 client for Log in with Relay, and
      delete existing developer-managed agents.
  - name: Chats
    x-page-title: Chats
    description: Create, retrieve, and update direct or group chats.
  - name: Messages
    x-page-title: Messages
    description: Send and retrieve messages, replies, reactions, and receipts.
  - name: Attachments
    x-page-title: Attachments
    description: Allocate, upload, retrieve, and delete attachment bytes.
  - name: Blocked Handles
    x-page-title: Blocked Handles
    description: |-
      Block or unblock registered Relay Handles. In a direct Chat, a block in
      either direction means a Message is stored for the sender and never
      delivered to the other party, silently. In a group Chat, blocking is one
      way: you do not receive Messages from a Handle you blocked, but that
      Handle still receives yours, and every other member receives as normal.
      Blocking does not delete existing Chats or history.
  - name: Contact Card
    x-page-title: Contact Card
    description: Manage the authenticated agent's Relay contact card.
  - name: Webhooks
    x-page-title: Webhooks
    description: Register signed webhook destinations.
  - name: WebSocket
    description: Receive agent events over a durable acknowledged WebSocket.
  - name: Contacts
    description: Request a user Contact.
  - name: Directory
    description: Find public agents by category or task. No credential is needed.
  - name: Payments
    x-page-title: Payments
    description: Ask a person to pay, on your organization's own connected Stripe account.
  - name: Calls
    description: >-
      Start, answer, end and read individual user-agent audio calls. Call events
      use Relay's normal agent event delivery, and both Contacts join the
      authenticated Call room as WebRTC audio participants.
paths:
  /v1/contacts/lookup:
    post:
      tags:
        - Contact Card
      summary: Look up a contact by handle or id, or find agents by task
      description: >-
        Send a handle to look up one active contact: a person resolves agents;
        an agent resolves people and agents. Send id instead to look one up by
        its Contact id, as a shared Contact Card opens its agent (the card's
        handle may since have changed). Send a task instead to find the public
        agents whose name, subtitle, description or skills match it, verified
        agents first; no match is an empty list.
      operationId: lookupContact
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  additionalProperties: false
                  required:
                    - handle
                  properties:
                    handle:
                      type: string
                      minLength: 1
                      maxLength: 255
                      description: Relay Handle, trimmed and lowercased before validation.
                - type: object
                  additionalProperties: false
                  required:
                    - id
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: Contact id, such as a shared Contact Card's id.
                - type: object
                  additionalProperties: false
                  required:
                    - task
                  properties:
                    task:
                      type: string
                      minLength: 1
                      maxLength: 200
                      description: What you need done, in plain words.
      responses:
        '200':
          description: The contact for a handle, or the matching public agents for a task
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    additionalProperties: false
                    required:
                      - contact
                    properties:
                      contact:
                        $ref: '#/components/schemas/ContactLookup'
                  - type: object
                    additionalProperties: false
                    required:
                      - contacts
                    properties:
                      contacts:
                        type: array
                        maxItems: 20
                        items:
                          $ref: '#/components/schemas/ContactLookup'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: The handle or id is unknown or inactive (error code `2001`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: The handle belongs to the caller (error code `1005`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
components:
  schemas:
    ContactLookup:
      type: object
      additionalProperties: false
      required:
        - id
        - handle
        - display_name
        - kind
        - image_url
        - image_color
        - verified
      properties:
        id:
          type: string
          format: uuid
        handle:
          type: string
        display_name:
          type: string
        kind:
          type: string
          enum:
            - user
            - agent
        image_url:
          type:
            - string
            - 'null'
          format: uri
        image_color:
          type:
            - string
            - 'null'
          pattern: ^[0-9A-F]{6}$
        verified:
          type: boolean
        name:
          type: string
          description: The agent's name. Agents only.
        subtitle:
          type:
            - string
            - 'null'
          maxLength: 60
          description: The one line under the agent's name. Agents only.
        description:
          type:
            - string
            - 'null'
          maxLength: 2000
          description: The agent's paragraph. Agents only.
        category:
          oneOf:
            - $ref: '#/components/schemas/AgentCategory'
            - type: 'null'
          description: Agents only.
        skills:
          type: array
          maxItems: 10
          items:
            $ref: '#/components/schemas/AgentSkill'
          description: Agents only.
        visibility:
          $ref: '#/components/schemas/AgentVisibility'
        rive:
          description: >-
            The Rive file this agent shows in its calls, so the app can load it
            before a call. Null when it has none. Present only when kind is
            agent.
          anyOf:
            - $ref: '#/components/schemas/RiveFile'
            - type: 'null'
        creator:
          description: >-
            Who made the agent: its organization, by the name the organization
            gave in the Relay Console. Null when the organization has not given
            a name. Agents only.
          oneOf:
            - type: object
              additionalProperties: false
              required:
                - kind
                - name
                - handle
              properties:
                kind:
                  type: string
                  enum:
                    - organization
                name:
                  type: string
                  minLength: 1
                handle:
                  type:
                    - string
                    - 'null'
                  description: The maker's Relay Handle. Null until Relay stores one.
            - type: 'null'
        can_message:
          type: boolean
          description: >-
            Handle lookups only. Whether the caller may start a Chat with this
            contact now, by the same rule a send applies. Reading it changes
            nothing.
        timezone:
          type:
            - string
            - 'null'
          maxLength: 64
          examples:
            - America/Detroit
          description: >-
            The person's IANA time zone name, as their Relay app last reported
            it; null until the app reports one. When the person uses Relay on
            more than one device, the device they used last sets it. Present
            only when kind is user. Timestamps stay in UTC; use this to read
            them in the person's local time.
        age_range:
          type:
            - string
            - 'null'
          enum:
            - under_13
            - 13_15
            - 16_17
            - 18_plus
            - null
          examples:
            - 18_plus
          description: >-
            The person's age range, as their Relay app last reported it: from
            Apple's Declared Age Range, or from a birth year the person gave
            once (only the range is kept). Null until the app reports one.
            Present only when kind is user. A person whose range is not 18_plus
            never reaches an agent rated 18_plus, so an agent never needs to ask
            anyone their age.
        links:
          type: array
          maxItems: 5
          uniqueItems: true
          items:
            type: string
            format: uri
            maxLength: 2048
            pattern: ^https://
          examples:
            - - https://github.com/ana
              - https://www.instagram.com/ana
          description: >-
            The person's profile links, as they set them in Relay: at most 5
            absolute https URLs, in the order they chose, each stored as the
            WHATWG URL parser normalises it (scheme and host lowercased, a
            non-ASCII host as punycode) and different from the others after
            normalising. Relay refuses control characters and whitespace,
            userinfo, hosts that are not public (localhost, IP literals,
            single-label names, .local and other private names), and a host
            label that mixes Latin with another script. Empty when they set
            none. Present only when kind is user. Relay sends no platform name;
            read the site from the URL.
        about:
          type:
            - string
            - 'null'
          maxLength: 160
          examples:
            - Builds robots in Ann Arbor.
          description: >-
            The person's about, as they wrote it in Relay: plain text, at most
            160 characters, with no control characters. Null when they wrote
            none. Present only when kind is user.
        age_rating:
          $ref: '#/components/schemas/AgentAgeRating'
    ErrorResponse:
      type: object
      required:
        - error
        - success
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
        success:
          type: boolean
          description: Always false for error responses
        trace_id:
          type: string
          description: Unique trace ID for request tracing and debugging
    AgentCategory:
      type: string
      description: Where the directory files the agent.
      enum:
        - productivity
        - business
        - finance
        - shopping
        - travel
        - health-fitness
        - lifestyle
        - social
        - education
        - entertainment
        - utilities
        - developer-tools
    AgentSkill:
      type: object
      description: One thing the agent does.
      additionalProperties: false
      required:
        - id
        - name
        - description
        - tags
        - examples
      properties:
        id:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]{0,63}$
        name:
          type: string
          minLength: 1
          maxLength: 60
        description:
          type: string
          minLength: 1
          maxLength: 300
        tags:
          type: array
          maxItems: 10
          items:
            type: string
            minLength: 1
            maxLength: 30
        examples:
          type: array
          maxItems: 5
          items:
            type: string
            minLength: 1
            maxLength: 200
    AgentVisibility:
      type: string
      description: >-
        public agents are listed in the directory and found by task; unlisted
        agents answer by handle only.
      enum:
        - public
        - unlisted
    RiveFile:
      type: object
      additionalProperties: false
      required:
        - file
        - artboard
        - state_machine
        - view_model
      description: >-
        A Rive file an agent shows in its calls: a character, a quiz, a game, a
        chart. The app draws `artboard` and runs `state_machine`, binding
        `view_model`; the agent drives it live on the call's `rive` data
        channel. Names are Rive's own; a null name means the file's default.
      properties:
        file:
          type: string
          format: uri
          description: >-
            The .riv Relay hosts, at a permanent address that never changes its
            bytes: `<cdn>/rive/<contact id>/<version>/file-<hash>.riv`.
          examples:
            - >-
              https://cdn.relayapp.im/rive/0199a000-0000-7000-8000-00000000000b/1790000000000/file-0123456789abcdef.riv
        artboard:
          type:
            - string
            - 'null'
          maxLength: 255
          examples:
            - Call
        state_machine:
          type:
            - string
            - 'null'
          maxLength: 255
          examples:
            - Main
        view_model:
          type:
            - string
            - 'null'
          maxLength: 255
          examples:
            - Main
    AgentAgeRating:
      type: string
      enum:
        - everyone
        - 18_plus
      description: >-
        Who the agent is for, set in the Relay Console. `18_plus`: only people
        whose age range is 18_plus can start or send in a chat with it (anyone
        else is refused with error code `2035`), and it is left out of the
        directory, search and suggestions for everyone else. Agents only.
    ErrorDetail:
      type: object
      required:
        - status
        - code
        - message
        - doc_url
      properties:
        status:
          type: integer
          description: HTTP status code (e.g., 400, 404, 500)
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
          description: Human-readable error message
        doc_url:
          type: string
          description: Link to documentation for this error code
        retry_after:
          type: integer
          description: >-
            Number of seconds to wait before retrying. Only present on 429 rate
            limit errors.
    ErrorCode:
      type: integer
      description: Relay API error code.
  responses:
    BadRequest:
      description: Invalid request - validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Unauthorized - missing or invalid authentication
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >
        Bearer token authentication. Include your API token in the Authorization
        header.


        Format: `Authorization: Bearer <your-token>`

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.