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

# Withdraw a pending invitation

> Withdraws a pending invitation. The adjuster can no longer accept it, and its status
becomes `withdrawn`. You can invite the same adjuster again later.

If the adjuster has already accepted, the request fails with `409 already_member`.
If there is no pending invitation for that OSAID in your firm, it fails with
`404 not_found`.




## OpenAPI

````yaml /openapi.yaml delete /v1/adjusters/invitations/{osa_id}
openapi: 3.1.0
info:
  title: OSA Partner API
  version: 1.0.0
  summary: Send claims to adjusters in the OSA app and follow their acceptance.
  description: >
    The OSA Partner API lets an adjusting firm's claims system invite adjusters
    to the firm,

    send them claims, and see whether each claim was accepted or rejected in the
    OSA app.


    **Conventions**

    - All requests and responses are JSON (`application/json`); errors use RFC
    9457 problem
      details (`application/problem+json`).
    - Field names are `snake_case`. Enum values are lowercase (for example
    `flood`,
      `pending_acceptance`), except US state and territory codes, which are the standard
      two-letter USPS codes, and flood zones, which are written as FEMA writes them (for
      example `AE`).
    - Enums are **open**: new values may be added to responses at any time, so
    your code must
      tolerate values it doesn't recognise.
    - Additive changes (new endpoints, new optional request fields, new response
    fields, new
      enum values) are made within `/v1`. Breaking changes go to a new version.
    - Requests are strict: an unknown or misspelled body field or query
    parameter is
      rejected with `422 validation_failed`, so typos can't be silently ignored.
    - Your own claim id (`external_id`) is stored on every claim and returned on
    every claim
      response, so you can match claims without keeping OSA's id.
    - Timestamps are RFC 3339 date-times in UTC. Dates that are calendar dates
    (such as the
      date of loss) are `YYYY-MM-DD` and are never converted between time zones.

    **Keys.** Every request except `GET /v1/health` needs an API key sent as

    `Authorization: Bearer <key>`. Live keys start with `osa_live_`; test keys
    start with

    `osa_test_` and only reach test claims and test accounts.
  contact:
    name: OSA API support
    email: info@osaconnection.com
    url: https://docs.osaconnection.com
servers:
  - url: https://api.osaconnection.com
    description: >-
      Production. Live and test keys both use this host; the key decides which
      data you reach.
security:
  - apiKey: []
tags:
  - name: Claims
    description: >
      Send claims to adjusters, offer them to another adjuster, and poll for
      acceptance.

      `/v1/claims` is always the claims your firm sent through the API.
  - name: Adjusters
    description: Invite adjusters to your firm by their OSAID and track their invitations.
  - name: Account
    description: Check which firm and permissions your API key carries.
  - name: Health
    description: Service availability. No key needed.
paths:
  /v1/adjusters/invitations/{osa_id}:
    delete:
      tags:
        - Adjusters
      summary: Withdraw a pending invitation
      description: >
        Withdraws a pending invitation. The adjuster can no longer accept it,
        and its status

        becomes `withdrawn`. You can invite the same adjuster again later.


        If the adjuster has already accepted, the request fails with `409
        already_member`.

        If there is no pending invitation for that OSAID in your firm, it fails
        with

        `404 not_found`.
      operationId: withdrawInvitation
      parameters:
        - $ref: '#/components/parameters/OsaIdPath'
      responses:
        '200':
          description: The invitation was withdrawn.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Adjuster'
              examples:
                withdrawn:
                  summary: Invitation withdrawn
                  value:
                    osa_id: Hp2sK8dL4fJ6gA1zX9cV3bN7mQ5w
                    status: withdrawn
                    test: false
                    name: null
                    email: null
                    invited_at: '2026-09-28T13:02:45Z'
                    expires_at: null
                    responded_at: null
                    invited_as: null
                    invited_by: null
                    purpose: null
                    note: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/AlreadyMember'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - apiKey:
            - adjusters:write
components:
  parameters:
    OsaIdPath:
      name: osa_id
      in: path
      required: true
      description: The OSAID of the adjuster whose invitation you are withdrawing.
      schema:
        $ref: '#/components/schemas/OsaId'
      examples:
        adjuster:
          summary: An invited adjuster's OSAID
          value: Hp2sK8dL4fJ6gA1zX9cV3bN7mQ5w
  headers:
    RequestId:
      description: >
        The id of this request. Quote it to OSA support. On error responses it
        equals

        `request_id` in the body.
      required: true
      schema:
        type: string
      examples:
        request_id:
          summary: A request id
          value: 7f3e9a1c2b4d6e8f0a1b3c5d7e9f1a2b
    RetryAfter:
      description: Seconds to wait before retrying.
      required: true
      schema:
        type: integer
        minimum: 1
      examples:
        seconds:
          summary: Retry in 12 seconds
          value: 12
  schemas:
    Adjuster:
      type: object
      description: An adjuster in your firm, or an invitation you sent.
      required:
        - osa_id
        - status
        - test
        - name
        - email
        - invited_at
        - expires_at
        - responded_at
        - invited_as
        - invited_by
        - purpose
        - note
      properties:
        osa_id:
          type: string
          description: The adjuster's OSAID.
        status:
          type: string
          description: >
            `pending`: invited, not yet answered. `active`: accepted and a
            member of your firm.

            `declined`: the adjuster declined. `expired`: not answered within 7
            days.

            `withdrawn`: you withdrew the invitation.
          enum:
            - pending
            - active
            - declined
            - expired
            - withdrawn
        test:
          type: boolean
          description: '`true` for one of your firm''s OSA-created test accounts.'
        name:
          type:
            - string
            - 'null'
          description: The adjuster's name; `null` until they accept.
        email:
          type:
            - string
            - 'null'
          description: The adjuster's email; `null` until they accept.
        invited_at:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            When the invitation was sent; `null` for members added without an
            invitation record.
        expires_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When a pending invitation expires; `null` unless pending.
        responded_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When the adjuster accepted or declined; `null` otherwise.
        invited_as:
          type:
            - string
            - 'null'
          description: >
            Who your firm said it was inviting; `null` when not sent. This is
            your firm's own

            note, so after acceptance it can differ from the account's real
            `name`.
        invited_by:
          type:
            - string
            - 'null'
          description: >-
            Who at your firm sent the invitation, as you sent it; `null` when
            not sent.
        purpose:
          type:
            - string
            - 'null'
          description: What the invitation is for, as you sent it; `null` when not sent.
        note:
          type:
            - string
            - 'null'
          description: >-
            Your firm's note on the invitation, as you sent it; `null` when not
            sent.
    OsaId:
      type: string
      description: >
        An adjuster's OSAID: their OSA account id. It exists once the adjuster
        has signed in to

        the OSA app, and they can read it from the app.
      minLength: 1
      maxLength: 128
      examples:
        - Xk3pQ9vT2mN8rL5wB7yC1dF4gH6j
    Problem:
      type: object
      description: >
        An RFC 9457 problem details object. Match on `code`, which is stable;
        `title` and

        `detail` are for people and may change. Quote `request_id` when
        contacting support.
      required:
        - type
        - title
        - status
        - detail
        - code
        - request_id
      properties:
        type:
          type: string
          format: uri
          description: A link to this error's documentation.
        title:
          type: string
          description: A short summary of the error.
        status:
          type: integer
          description: The HTTP status code.
        detail:
          type: string
          description: What went wrong in this request.
        code:
          type: string
          description: >
            The stable error code. `malformed_request` (400); `invalid_key`
            (401);

            `insufficient_scope`, `not_in_plan` (403); `not_found` (404);
            `duplicate_claim`,

            `claim_already_accepted`, `already_member`, `invitation_pending`
            (409);

            `payload_too_large` (413); `validation_failed`,
            `idempotency_key_reused`,

            `unknown_osaid`, `adjuster_not_in_firm`, `adjuster_not_accepting`,

            `environment_mismatch` (422); `rate_limited` (429); `internal_error`
            (500). New codes

            may be added.
          enum:
            - malformed_request
            - invalid_key
            - insufficient_scope
            - not_in_plan
            - not_found
            - duplicate_claim
            - claim_already_accepted
            - already_member
            - invitation_pending
            - payload_too_large
            - validation_failed
            - idempotency_key_reused
            - unknown_osaid
            - adjuster_not_in_firm
            - adjuster_not_accepting
            - environment_mismatch
            - rate_limited
            - internal_error
        request_id:
          type: string
          description: The id of this request. Quote it when contacting support.
        errors:
          type: array
          description: For `validation_failed`, each invalid field, parameter or header.
          items:
            type: object
            description: >-
              One problem. Exactly one of `pointer`, `parameter` or `header`
              says where.
            required:
              - detail
            properties:
              pointer:
                type: string
                description: >-
                  JSON Pointer to a body field, for example `/loss/date`. Empty
                  for the whole body.
              parameter:
                type: string
                description: The name of a query or path parameter, for example `limit`.
              header:
                type: string
                description: The name of a request header, for example `Idempotency-Key`.
              detail:
                type: string
                description: What is wrong with it.
        existing_claim_id:
          type: string
          format: uuid
          description: >-
            For `duplicate_claim`, the id of the claim that already exists.
            Always a claim your key can read.
        existing_claim_url:
          type: string
          format: uri
          description: >-
            For `duplicate_claim`, the API link to the claim that already
            exists. Always a claim your key can read.
  responses:
    Unauthorized:
      description: >
        The key is missing, malformed, unknown, revoked or expired
        (`invalid_key`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            invalid_key:
              summary: invalid_key
              value:
                type: https://docs.osaconnection.com/errors#invalid_key
                title: Invalid API key
                status: 401
                detail: The API key is missing, malformed, revoked or expired.
                code: invalid_key
                request_id: 7f3e9a1c2b4d6e8f0a1b3c5d7e9f1a2b
    Forbidden:
      description: >
        The key is valid but can't do this. `insufficient_scope`: the key's
        purpose doesn't

        include the permission this operation needs. `not_in_plan`: your firm's
        plan doesn't

        include it.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            insufficient_scope:
              summary: insufficient_scope
              value:
                type: https://docs.osaconnection.com/errors#insufficient_scope
                title: Insufficient scope
                status: 403
                detail: This key doesn't have the claims:write permission.
                code: insufficient_scope
                request_id: 0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e
            not_in_plan:
              summary: not_in_plan
              value:
                type: https://docs.osaconnection.com/errors#not_in_plan
                title: Not in plan
                status: 403
                detail: Your firm's plan doesn't include adjuster invitations.
                code: not_in_plan
                request_id: 1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f
    NotFound:
      description: >
        Nothing with this id exists in your firm, or your key can't see it
        (`not_found`).

        Another firm's claim, and a real claim requested with a test key, both
        return this.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            not_found:
              summary: not_found
              value:
                type: https://docs.osaconnection.com/errors#not_found
                title: Not found
                status: 404
                detail: No claim with this id exists in your firm.
                code: not_found
                request_id: 2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a
    AlreadyMember:
      description: The adjuster has already accepted the invitation (`already_member`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            already_member:
              summary: already_member
              value:
                type: https://docs.osaconnection.com/errors#already_member
                title: Already a member
                status: 409
                detail: >-
                  This adjuster has already accepted your invitation, so there
                  is nothing to withdraw.
                code: already_member
                request_id: 7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f
    ValidationFailed:
      description: >
        The request is invalid (`validation_failed`): a missing, unknown or
        invalid body field,

        query parameter, path parameter or header. `errors` lists each problem:
        `pointer` for a

        body field, `parameter` for a query or path parameter, `header` for a
        header.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            validation_failed:
              summary: validation_failed
              value:
                type: https://docs.osaconnection.com/errors#validation_failed
                title: Validation failed
                status: 422
                detail: The request has 1 invalid field.
                code: validation_failed
                request_id: 8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a
                errors:
                  - parameter: limit
                    detail: must be <= 200
    RateLimited:
      description: >
        Too many requests for this key (`rate_limited`). Wait for the number of
        seconds in

        `Retry-After`, then retry.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            rate_limited:
              summary: rate_limited
              value:
                type: https://docs.osaconnection.com/errors#rate_limited
                title: Rate limited
                status: 429
                detail: This key has exceeded 300 requests per minute.
                code: rate_limited
                request_id: 9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f
    InternalError:
      description: >
        Something failed on OSA's side (`internal_error`). Retry with
        exponential backoff; for

        `POST` requests, reuse the same `Idempotency-Key`. If it persists,
        contact OSA with the

        `request_id`.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            internal_error:
              summary: internal_error
              value:
                type: https://docs.osaconnection.com/errors#internal_error
                title: Internal error
                status: 500
                detail: Something went wrong on our side. Retry later.
                code: internal_error
                request_id: 2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: osa_live_… or osa_test_…
      description: >
        Send your API key as a bearer token: `Authorization: Bearer osa_live_…`.

        Keys are opaque; each belongs to exactly one firm and one purpose. Keys
        starting with

        `osa_test_` reach only test claims and test accounts. The scopes listed
        on each

        operation are the permissions the key needs; `GET /v1/me` shows the ones
        your key has.

````

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