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

# Hand back a running step without settling it

> For a step this browser cannot go on with here: it looked and found the step not done but may not finish it now, the person closed the working tab again, no window is open, or the page stopped under it. A step that may have touched LinkedIn goes back to be looked at again; any other goes back to the line, giving back its daily unit and its credit hold. Only `interrupted` counts against the step, and the fourth time fails it for a person to retry. A step no longer claimed by this browser is refused with 409.



## OpenAPI

````yaml /openapi.json post /linkedin/agent/actions/{action_id}/release/
openapi: 3.1.0
info:
  contact:
    email: support@getoneprofile.ai
    name: Oneprofile Support
  description: >-
    REST API reference for Oneprofile, the GTM data layer for your CRM. Manage
    tables, enrichments, and integrations. Authenticate with an API key to get
    started.
  termsOfService: https://www.getoneprofile.ai/terms
  title: API Reference | Oneprofile
  version: '0.0'
servers:
  - url: https://api.getoneprofile.ai
security: []
tags:
  - description: >-
      The docked AI Assistant: its general chat about the workspace and the
      product, streamed as Server-Sent Events, and the one list of a person's
      threads across every assistant, with pin, rename, delete and the
      search-to-table link.
    name: assistant
  - description: >-
      The messages a person keeps to send the assistant again: the ones the
      workspace saved and the ones that ship with the product, with save,
      rename, edit and delete.
    name: assistant-prompt
  - description: >-
      Granted workspace actions: what the AI Assistant proposed or applied in a
      conversation, the approve and dismiss decisions on each card, the
      workspace's approval threshold and default grants, and the eight verbs.
    name: workspace-actions
  - description: >-
      The Getting started checklist: a workspace's progress through the six
      steps from its first people search to its first launched sequence.
    name: onboarding
  - description: Senders, connected mailboxes, tags, and the Google connect flow.
    name: senders
  - description: The workspace do-not-contact list, enforced before every send.
    name: suppression
  - description: >-
      The workspace's recontact rule: how long before anyone hears from us
      again.
    name: contact_cooldown
  - description: 'Sequence authoring: the graph, the table-backed audience, previews.'
    name: sequences
  - description: >-
      The outbound agent behind a sequence: the voice it writes in, its
      per-message prompts, what it wrote and what people told it.
    name: outbound-agents
  - description: >-
      The LinkedIn channel: connecting an account to a sender, its safety limits
      and history, and the protocol the browser extension speaks.
    name: linkedin
  - description: >-
      The approval queue: everything waiting on a person across every sender and
      channel, and the workspace's manual or automatic modes per channel.
    name: outreach
  - description: 'The unified outreach inbox: threads, replies, labels, events.'
    name: inbox
  - description: 'The AI reply layer: workspace settings, drafts, and approval.'
    name: inbox-ai
  - description: Notification rules, per-user preferences, and the Slack connection.
    name: notifications
  - description: Endpoints for seeing all available integration types.
    name: integration-types
  - description: Endpoints for creating and managing integrations.
    name: integrations
  - description: Endpoints for the generic OAuth install/claim app-listings engine.
    name: app-listings
  - description: Endpoints for creating and managing API keys.
    name: apikey
  - description: >-
      The Model Context Protocol endpoint: use Oneprofile from Claude Code,
      Claude Desktop, Cursor or any other MCP client, with an API key as the
      bearer token.
    name: mcp
  - description: Endpoints for managing billing and subscription information.
    name: billing
  - description: Endpoints for creating and managing tables.
    name: tables
  - description: Endpoints for table columns, formula previews, and on-demand column runs.
    name: table-columns
  - description: Endpoints for table rows and manual cell edits.
    name: table-rows
  - description: Endpoints for observing and cancelling table recompute runs.
    name: table-runs
  - description: >-
      Endpoints for org-shared per-column display preferences: hidden, pinned,
      width, and colour tint.
    name: table-ui-prefs
  - description: >-
      Endpoints for the org-shared names given to the column tint palette: what
      this organisation calls each colour. Org-level, not per-table.
    name: table-column-color-labels
  - description: >-
      Endpoints for the enrichment action catalog, model list, presets, draft
      generation, and saved agents.
    name: table-enrichments
  - description: >-
      Endpoints for teaching a saved agent from example rows: training sessions,
      per-row feedback, and the proposed prompt to approve.
    name: agent-training
  - description: >-
      The durable audit trail of a table's enrichment actions: configured,
      edited, run, cancelled, and settled cost.
    name: table-enrichment-audit-logs
  - description: Endpoints for saving and applying column templates.
    name: table-templates
  - description: Server-sent change feed for a table's grid.
    name: table-events
  - description: 'Endpoints for org-shared saved table views: sort, filters, hidden columns.'
    name: table-views
  - description: >-
      Endpoints for PER-USER table preferences: favourites and recently opened.
      Unlike the rest of the table surface these are personal, so two members of
      one organisation legitimately see different answers.
    name: table-user-prefs
  - description: >-
      Endpoints for building a table from an uploaded CSV: upload and preview
      the inferred columns, commit the reviewed mapping, then poll the row load.
    name: table-imports
  - description: Endpoint for downloading a table's rows as CSV.
    name: table-export
  - description: >-
      Endpoints for the integration a table imports from: attach and preview it,
      promote imported fields into columns, and run the import on demand.
    name: table-sources
  - description: >-
      Endpoints for a table's recurring import cadence: set it, pause it, and
      read the next fire times.
    name: table-schedules
  - description: >-
      Endpoints for pushing a table's rows out to a connected integration: list
      writable destinations, derive their write capabilities, and map export
      columns.
    name: table-writeback
  - description: >-
      Endpoints backing a lookup column's setup: the connections whose records a
      column could read, and the identity fields one record type can be looked
      up by.
    name: table-integration-lookup
  - description: >-
      Endpoints for sourcing leads from the lead database: count and preview
      matches, land them in a table, and keep saved searches. Alongside people
      and company searches, leads can be sourced from buying signals (what a
      company or person just did), with a catalogue endpoint behind the picker
      that builds them.
    name: find-leads
  - description: >-
      Endpoints for discovering a domain's subdomains from public certificate
      logs and landing the results in a table.
    name: find-subdomains
  - description: Endpoints for the credit balance meter and usage reporting.
    name: credits
  - description: >-
      Endpoints for the workspace referral program: the shareable link, the
      friends who joined through it, and claiming a code after signup.
    name: referral
  - description: >-
      Endpoints for the affiliate program's own dashboard: enrolling and
      claiming a code, the summary, stats and activity feed, the commission
      ledger, and identity verification and payouts.
    name: affiliate
  - description: >-
      Endpoints for the design partner program's customer surface: whether this
      workspace is a design partner, the badges its feedback has earned, and
      sending and reading that feedback.
    name: design-partner
  - description: >-
      Endpoints for the org-level AI business context (company description,
      ideal customer profile, buyer personas, interest signals and social
      proof), plus domain-based generation and the reference documents whose
      summaries ride alongside those fields.
    name: ai-context
  - description: >-
      Endpoints for the signed-in user's Google Drive connection: starting and
      finishing the OAuth grant, checking or dropping it, and minting the
      short-lived token the Google Picker needs.
    name: google-drive
paths:
  /linkedin/agent/actions/{action_id}/release/:
    post:
      tags:
        - linkedin
      summary: Hand back a running step without settling it
      description: >-
        For a step this browser cannot go on with here: it looked and found the
        step not done but may not finish it now, the person closed the working
        tab again, no window is open, or the page stopped under it. A step that
        may have touched LinkedIn goes back to be looked at again; any other
        goes back to the line, giving back its daily unit and its credit hold.
        Only `interrupted` counts against the step, and the fourth time fails it
        for a person to retry. A step no longer claimed by this browser is
        refused with 409.
      operationId: linkedin_agent_release
      parameters:
        - in: path
          name: action_id
          required: true
          schema:
            format: uuid
            title: Action Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentReleaseSchema'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinkedInActionReadSchema'
          description: Successful Response
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedResponse'
          description: The agent token is invalid, revoked, or expired.
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenResponse'
          description: Forbidden
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundResponse'
          description: No such action on the account this token is bound to.
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundResponse'
          description: The step is not this browser's.
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnprocessableEntityResponse'
          description: Invalid request made to the API.
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Internal server error.
        '502':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Bad gateway error.
        '503':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
          description: Service unavailable.
      security:
        - APIKeyHeader: []
components:
  schemas:
    AgentReleaseSchema:
      properties:
        claimed_at:
          description: The step's claim, exactly as the claim handed it out.
          format: date-time
          title: Claimed At
          type: string
        reason:
          $ref: '#/components/schemas/LinkedInReleaseReason'
          description: >-
            verified_absent (looked, not done, may not finish it now) or
            reopen_paused (the person closed the tab again). Neither counts
            against the step: a run cut off under it is reported to the attempts
            endpoint.
      required:
        - claimed_at
        - reason
      title: AgentReleaseSchema
      type: object
    LinkedInActionReadSchema:
      description: >-
        One LinkedIn step, in the shape the dashboard and every extension build
        read.


        A step is queued only once it may run (its approval, when one was asked

        for, happened on Tasks before it was queued), so every step reads

        ``approved_at`` as the moment it was queued and ``requires_approval``

        false: the extension's store builds draw "Approve tasks" from exactly

        these two fields, and no step in the line waits for a person. ``hold``
        is

        kept for the same builds and is always null: whether a step is out of
        the

        line is ``held``.
      properties:
        account_id:
          format: uuid
          title: Account Id
          type: string
        acted_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: >-
            When the step said it acted on LinkedIn, for a result that arrived
            late. On a failed step it means the step happened after all: it
            stays failed for a person, and a Retry checks LinkedIn first and
            never sends it twice.
          title: Acted At
        approved_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          description: >-
            When the step was let run: the moment it was queued, since a step is
            queued only once it may run. Kept for older extension builds.
          title: Approved At
        claimed_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Claimed At
        duration_ms:
          anyOf:
            - type: integer
            - type: 'null'
          title: Duration Ms
        error_code:
          anyOf:
            - $ref: '#/components/schemas/LinkedInAgentErrorCode'
            - type: 'null'
        error_message:
          anyOf:
            - type: string
            - type: 'null'
          title: Error Message
        finished_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Finished At
        held:
          default: false
          description: >-
            Whether the step is held out of every browser's line, because its
            paused sequence or paused contact holds it. It runs once they are
            resumed. Only the dashboard's queue lists a held step that is
            waiting; a browser is never sent one.
          title: Held
          type: boolean
        hold:
          anyOf:
            - $ref: '#/components/schemas/StepHold'
            - type: 'null'
          description: Always null; read `held`. Kept for older extension builds.
        id:
          format: uuid
          title: Id
          type: string
        kind:
          $ref: '#/components/schemas/LinkedInActionKind'
        metered:
          default: true
          description: >-
            Whether the step spends the sender's limits and credit. False for a
            step the Oneprofile team fired to test the sender: it goes first,
            waits for no gap and counts against no limit.
          title: Metered
          type: boolean
        outcome:
          anyOf:
            - $ref: '#/components/schemas/LinkedInActionOutcome-Output'
            - type: 'null'
        params:
          $ref: '#/components/schemas/LinkedInActionParams'
        queued_at:
          format: date-time
          title: Queued At
          type: string
        requires_approval:
          default: false
          description: >-
            Always false: a step that asks for a person waits on Oneprofile's
            Tasks page, never in the line. Kept for older extension builds.
          title: Requires Approval
          type: boolean
        status:
          $ref: '#/components/schemas/LinkedInActionStatus'
      required:
        - id
        - account_id
        - kind
        - params
        - status
        - outcome
        - error_code
        - error_message
        - queued_at
        - claimed_at
        - finished_at
        - duration_ms
      title: LinkedInActionReadSchema
      type: object
    UnauthorizedResponse:
      properties:
        detail:
          description: The detail of why the request is unauthorized.
          title: Detail
          type: string
      required:
        - detail
      title: UnauthorizedResponse
      type: object
    ForbiddenResponse:
      properties:
        detail:
          description: The detail of why the request is forbidden.
          title: Detail
          type: string
      required:
        - detail
      title: ForbiddenResponse
      type: object
    NotFoundResponse:
      properties:
        detail:
          description: The detail of why the resource was not found.
          title: Detail
          type: string
      required:
        - detail
      title: NotFoundResponse
      type: object
    UnprocessableEntityResponse:
      properties:
        detail:
          description: >-
            The detail of the error. This is the error message to show to the
            user. You should also use the issues field to show more detailed
            error messages per field. Use this field for a single liner error
            message.
          title: Detail
          type: string
        issues:
          description: >-
            The issues that caused the error. There can be multiple issues. Each
            issue is a user-facing error message.
          items:
            $ref: '#/components/schemas/UnprocessableEntityIssue'
          title: Issues
          type: array
      required:
        - detail
        - issues
      title: UnprocessableEntityResponse
      type: object
    ServerErrorResponse:
      properties:
        detail:
          description: The detail of why the server returned an error.
          title: Detail
          type: string
      required:
        - detail
      title: ServerErrorResponse
      type: object
    LinkedInReleaseReason:
      description: >-
        Why a browser handed back a step it holds without settling it.


        ``verified_absent``: it looked and found the step not done, and may not

        finish it now (a held or cancelled step's look). ``reopen_paused``: the

        person closed the working tab again, so this browser stopped reopening
        it.

        Neither counts against the step: a run cut off under it is reported as
        an

        attempt instead.
      enum:
        - verified_absent
        - reopen_paused
      title: LinkedInReleaseReason
      type: string
    LinkedInAgentErrorCode:
      description: >-
        Why one action did not succeed, as a closed vocabulary.


        Two populations in one enum, on purpose. The first twelve are reported
        by

        the browser agent and were previously a free string that only the
        extension

        had written down, so nothing stopped a typo storing and rendering
        exactly like

        a real code. The last four the backend writes itself: three when an
        action

        settles without the browser ever running it, and ``CLAIM_EXPIRED`` when
        the

        browser took a step and then went silent, so nobody can say whether it
        ran.


        The list is the whole contract: a code outside it is rejected at the API

        boundary rather than persisted, so the extension and the dashboard can
        only

        ever speak about failures both sides can name.
      enum:
        - selector_missing
        - blocked_checkpoint
        - not_authenticated
        - account_mismatch
        - navigation_failed
        - timed_out
        - linkedin_error
        - agent_restarted
        - tab_lost
        - not_applicable
        - not_connected
        - invalid_params
        - user_rejected
        - cancelled
        - missed_window
        - sender_changed
        - claim_expired
        - interrupted_repeatedly
      title: LinkedInAgentErrorCode
      type: string
    StepHold:
      description: >-
        Why a sequence's step may not run now, whatever its approval says.


        A paused sequence or a paused contact sends nothing on either channel;
        an

        approval given meanwhile waits for **Resume sequence** (or the contact's

        own resume).
      enum:
        - sequence_paused
        - contact_paused
      title: StepHold
      type: string
    LinkedInActionKind:
      description: >-
        What the browser agent is being asked to do.


        The four ``CHECK_*``/``READ_*`` kinds are housekeeping: they read our
        own

        outbound invitations, our own newest connections and our own
        conversations to

        detect what the contact did, so they are free and deliberately excluded
        from

        the priced kinds below.


        ``CHECK_CONNECTIONS`` reads the first batch of the sender's connections
        list,

        newest first: a person found there has accepted, whenever the invitation

        went out. It is how an acceptance is noticed at all once an invitation
        has

        fallen out of the ten rows the sent list shows a background tab.


        ``CHECK_INBOX`` scans the conversation list for threads with new inbound

        activity; ``READ_CONVERSATION`` opens one of them and reads it in full.
        The

        split keeps LinkedIn activity proportional to real replies: the cheap
        scan

        runs on every sweep, the expensive read only where the scan saw a
        change.


        ``LIKE_LATEST_POST`` targets the contact's most recent post at the
        moment

        the browser runs it. A contact with no posts is not a failure: the
        driver

        reports the action ``SKIPPED``, and the sequence advances either way.


        Every profile-targeted outcome carries the facts the browser read off
        the

        profile, including the three-state Premium "Open Profile" reading; see
        the

        section comment above the outcome models.
      enum:
        - profile_view
        - connection_request
        - send_message
        - inmail
        - withdraw_connection_request
        - follow_contact
        - like_latest_post
        - check_sent_invitations
        - check_connections
        - check_inbox
        - read_conversation
      title: LinkedInActionKind
      type: string
    LinkedInActionOutcome-Output:
      description: |-
        What one action reported back. Consumers read the member via ``.root``.

        Null on the row while the action is queued or claimed, and on a row the
        backend settled unrun by rejection or cancellation; a document of the
        matching member once a browser ran it or expiry settled it.
      discriminator:
        mapping:
          check_connections: '#/components/schemas/CheckConnectionsOutcome'
          check_inbox: '#/components/schemas/CheckInboxOutcome'
          check_sent_invitations: '#/components/schemas/CheckSentInvitationsOutcome'
          connection_request: '#/components/schemas/ConnectionRequestOutcome'
          follow_contact: '#/components/schemas/FollowContactOutcome'
          inmail: '#/components/schemas/InMailOutcome'
          like_latest_post: '#/components/schemas/LikeLatestPostOutcome'
          profile_view: '#/components/schemas/ProfileViewOutcome'
          read_conversation: '#/components/schemas/ReadConversationOutcome'
          send_message: '#/components/schemas/SendMessageOutcome'
          withdraw_connection_request: '#/components/schemas/WithdrawConnectionRequestOutcome'
        propertyName: kind
      oneOf:
        - $ref: '#/components/schemas/ProfileViewOutcome'
        - $ref: '#/components/schemas/ConnectionRequestOutcome'
        - $ref: '#/components/schemas/SendMessageOutcome'
        - $ref: '#/components/schemas/InMailOutcome'
        - $ref: '#/components/schemas/WithdrawConnectionRequestOutcome'
        - $ref: '#/components/schemas/FollowContactOutcome'
        - $ref: '#/components/schemas/LikeLatestPostOutcome'
        - $ref: '#/components/schemas/CheckSentInvitationsOutcome'
        - $ref: '#/components/schemas/CheckConnectionsOutcome'
        - $ref: '#/components/schemas/CheckInboxOutcome'
        - $ref: '#/components/schemas/ReadConversationOutcome'
      title: LinkedInActionOutcome
    LinkedInActionParams:
      description: What one action is asked to do. Consumers read the member via ``.root``.
      discriminator:
        mapping:
          check_connections: '#/components/schemas/CheckConnectionsParams'
          check_inbox: '#/components/schemas/CheckInboxParams'
          check_sent_invitations: '#/components/schemas/CheckSentInvitationsParams'
          connection_request: '#/components/schemas/ConnectionRequestParams'
          follow_contact: '#/components/schemas/FollowContactParams'
          inmail: '#/components/schemas/InMailParams'
          like_latest_post: '#/components/schemas/LikeLatestPostParams'
          profile_view: '#/components/schemas/ProfileViewParams'
          read_conversation: '#/components/schemas/ReadConversationParams'
          send_message: '#/components/schemas/SendMessageParams'
          withdraw_connection_request: '#/components/schemas/WithdrawConnectionRequestParams'
        propertyName: kind
      oneOf:
        - $ref: '#/components/schemas/ProfileViewParams'
        - $ref: '#/components/schemas/ConnectionRequestParams'
        - $ref: '#/components/schemas/SendMessageParams'
        - $ref: '#/components/schemas/InMailParams'
        - $ref: '#/components/schemas/WithdrawConnectionRequestParams'
        - $ref: '#/components/schemas/FollowContactParams'
        - $ref: '#/components/schemas/LikeLatestPostParams'
        - $ref: '#/components/schemas/CheckSentInvitationsParams'
        - $ref: '#/components/schemas/CheckConnectionsParams'
        - $ref: '#/components/schemas/CheckInboxParams'
        - $ref: '#/components/schemas/ReadConversationParams'
      title: LinkedInActionParams
    LinkedInActionStatus:
      description: >-
        Where one queued action stands.


        Governor-deferral is deliberately NOT a status: an action whose kind has
        hit

        its daily cap stays ``QUEUED`` and is simply not handed out, with the
        reason

        travelling on the hand-out response instead. A ``DEFERRED`` row would
        make

        the queue lie about what is still waiting to happen.


        ``SKIPPED`` is "not applicable" (no LinkedIn URL, already connected);

        ``REJECTED`` is "a human refused it"; ``FAILED`` is "we tried and could
        not".


        ``RESUMING`` is a step put back in line after an attempt that may have

        acted on LinkedIn (its browser was granted the press, or lost track of
        the

        step): it is never "queued", so no path that assumes nothing happened
        yet

        (moving it to another sender, a plain copy, "did not run") ever reads it
        as

        such, and it is handed only to a browser that checks LinkedIn before
        acting.
      enum:
        - queued
        - resuming
        - claimed
        - succeeded
        - failed
        - rejected
        - skipped
      title: LinkedInActionStatus
      type: string
    UnprocessableEntityIssue:
      properties:
        input:
          anyOf:
            - type: string
            - type: integer
            - type: number
            - type: boolean
            - items: {}
              type: array
            - additionalProperties: true
              type: object
          description: The user's input that caused the error.
          title: Input
        loc:
          description: >-
            The location of the error. Always contains 1 or 2 elements. The
            first element is the type of location (e.g. 'body', 'query', 'path',
            'header'). The second element is the name of the field that caused
            the error. If the error is not related to a specific field, the
            second element is not present.
          items:
            type: string
          title: Loc
          type: array
        msg:
          description: The message of the error. The error message to show to the user.
          title: Msg
          type: string
        type:
          description: >-
            The type of the error. Useful for frontend code to handle different
            types of errors.
          title: Type
          type: string
      required:
        - loc
        - msg
        - type
        - input
      title: UnprocessableEntityIssue
      type: object
    CheckConnectionsOutcome:
      additionalProperties: false
      description: >-
        One reading of our own connections list, newest connection first.


        ``rows`` are what the browser reported; the server keeps them on the

        reading's own log row and strips them from here before the action
        settles,

        so this document ends up with the counts only (``rows_read``,

        ``rows_unread``) and nobody's key outlives its retention on a step's
        row.


        ``member_urn`` echoes the salt every key was hashed with

        (``CheckConnectionsParams.member_urn``); a reading salted for any member

        but the account's proves nothing. ``sort_proven`` says the list was
        shown

        "Recently added" by a token that cannot be a position or a word; a
        reading

        that cannot prove it is never judged, though the members it lists are

        still matched. ``stable`` says two snapshots taken apart agreed.
        ``empty``

        is LinkedIn's own empty-list surface. ``pages`` counts the batches read

        (one, plus each "Show more"), ``more_available`` whether LinkedIn
        offered

        another, ``reached_watermark`` whether the reading got back to the last

        one's rows. ``named_by`` says which spellings rows carried, which
        decides

        which ledger rows a reading can match at all.
      properties:
        complete:
          default: false
          title: Complete
          type: boolean
        empty:
          default: false
          title: Empty
          type: boolean
        kind:
          const: check_connections
          default: check_connections
          title: Kind
          type: string
        member_urn:
          maxLength: 128
          title: Member Urn
          type: string
        more_available:
          anyOf:
            - type: boolean
            - type: 'null'
          title: More Available
        named_by:
          items:
            enum:
              - vanity
              - member
              - fsd_profile
            type: string
          maxItems: 3
          title: Named By
          type: array
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        pages:
          default: 0
          maximum: 6
          minimum: 0
          title: Pages
          type: integer
        reached_watermark:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Reached Watermark
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        rows:
          items:
            $ref: '#/components/schemas/LinkedInConnectionRow'
          maxItems: 400
          title: Rows
          type: array
        rows_read:
          anyOf:
            - maximum: 400
              minimum: 0
              type: integer
            - type: 'null'
          title: Rows Read
        rows_unread:
          anyOf:
            - maximum: 400
              minimum: 0
              type: integer
            - type: 'null'
          title: Rows Unread
        sort_proven:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Sort Proven
        stable:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Stable
      required:
        - member_urn
      title: CheckConnectionsOutcome
      type: object
    CheckInboxOutcome:
      additionalProperties: false
      description: |-
        One reading of the conversation list.

        Rows the scan could not name are why a reading is not ``complete``.
      properties:
        complete:
          default: false
          title: Complete
          type: boolean
        conversations:
          items:
            $ref: '#/components/schemas/LinkedInConversationRow'
          maxItems: 500
          title: Conversations
          type: array
        kind:
          const: check_inbox
          default: check_inbox
          title: Kind
          type: string
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
      title: CheckInboxOutcome
      type: object
    CheckSentInvitationsOutcome:
      additionalProperties: false
      description: >-
        One reading of the sent-invitations list, as the members still
        outstanding.


        A list with no rows is only ``complete`` when LinkedIn's own empty-list

        surface was seen, because the list loading is the action here and a list

        that never rendered is an honest failure. Every urn the reading omits is

        marked disappeared, a state that does not recover on the next reading,
        so

        a reading with a row it could not name is reported and never complete.


        The list LinkedIn renders now names each member only by the
        ``/in/<slug>``

        of their profile link, and draws the newest rows first with the rest

        loading on scroll, which a background tab never does: ``newest_only`` is

        such a reading, the top of the list and not all of it, and is judged
        only

        as far down as it reaches (see ``sql_repository.apply_sweep``).
      properties:
        complete:
          default: false
          title: Complete
          type: boolean
        kind:
          const: check_sent_invitations
          default: check_sent_invitations
          title: Kind
          type: string
        newest_only:
          default: false
          title: Newest Only
          type: boolean
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        still_pending_urns:
          items:
            maxLength: 128
            type: string
          maxItems: 2000
          title: Still Pending Urns
          type: array
        still_pending_vanities:
          items:
            maxLength: 200
            type: string
          maxItems: 2000
          title: Still Pending Vanities
          type: array
      title: CheckSentInvitationsOutcome
      type: object
    ConnectionRequestOutcome:
      additionalProperties: false
      description: >-
        What sending an invitation produced: the common fields and the nine
        profile facts.


        The facts are read twice: before pressing Connect, which is what decides

        whether there is anything to send, and again after the invitation window

        closed, which is the verification. An invitation that went out shows as

        ``invitation_pending`` on re-reading; a re-reading that shows Connect
        back

        on offer is a failure, whatever the window did.


        ``member_urn`` is the load-bearing field: without it the invitation
        ledger

        row never opens and acceptance detection has nothing to match. Whether a

        note went with the invitation is the step's own ``note``: the browser

        sends exactly what it was handed or fails rather than send less, and how

        far a failed attempt got is the row's error message. The one exception
        is

        ``sent_without_note``: True when LinkedIn sent the invitation the moment

        Connect was pressed, with no window to write the note in. The invitation

        exists, so the step succeeded; the note it was handed did not go with
        it.

        None whenever the note went (or there was none to send). Not
        ``note_sent``:

        that key was retired, and the release task strips it from stored rows.
      properties:
        already_connected:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Connected
        already_following:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Following
        can_send_message:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Can Send Message
        found_already:
          anyOf:
            - $ref: '#/components/schemas/LinkedInFoundAlready'
            - type: 'null'
        invitation_pending:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Invitation Pending
        kind:
          const: connection_request
          default: connection_request
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        member_urns:
          items:
            maxLength: 128
            type: string
          maxItems: 8
          title: Member Urns
          type: array
        open_profile:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Open Profile
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        profile_resolved:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Profile Resolved
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        sent_without_note:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Sent Without Note
        vanity:
          anyOf:
            - type: string
            - type: 'null'
          title: Vanity
      title: ConnectionRequestOutcome
      type: object
    FollowContactOutcome:
      additionalProperties: false
      description: >-
        What following a member produced: the common fields and the nine profile
        facts.


        ``already_following`` re-read after the click is the verification.
      properties:
        already_connected:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Connected
        already_following:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Following
        can_send_message:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Can Send Message
        found_already:
          anyOf:
            - $ref: '#/components/schemas/LinkedInFoundAlready'
            - type: 'null'
        invitation_pending:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Invitation Pending
        kind:
          const: follow_contact
          default: follow_contact
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        member_urns:
          items:
            maxLength: 128
            type: string
          maxItems: 8
          title: Member Urns
          type: array
        open_profile:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Open Profile
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        profile_resolved:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Profile Resolved
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        vanity:
          anyOf:
            - type: string
            - type: 'null'
          title: Vanity
      title: FollowContactOutcome
      type: object
    InMailOutcome:
      additionalProperties: false
      description: >-
        What sending an InMail produced: the common fields, the profile facts
        and the thread.


        ``conversation_urn`` links the thread exactly as it does for a direct

        message: read off the composer for a new thread, and the one the step
        was

        given for a reply, where the profile facts stay ``None`` because the

        messaging page shows no profile.
      properties:
        already_connected:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Connected
        already_following:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Following
        can_send_message:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Can Send Message
        conversation_urn:
          anyOf:
            - maxLength: 255
              type: string
            - type: 'null'
          title: Conversation Urn
        found_already:
          anyOf:
            - $ref: '#/components/schemas/LinkedInFoundAlready'
            - type: 'null'
        invitation_pending:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Invitation Pending
        kind:
          const: inmail
          default: inmail
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        member_urns:
          items:
            maxLength: 128
            type: string
          maxItems: 8
          title: Member Urns
          type: array
        open_profile:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Open Profile
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        profile_resolved:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Profile Resolved
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        vanity:
          anyOf:
            - type: string
            - type: 'null'
          title: Vanity
      title: InMailOutcome
      type: object
    LikeLatestPostOutcome:
      additionalProperties: false
      description: >-
        What liking the latest post produced: the common fields and the nine
        profile facts.


        A member with no posts is skipped, not failed.
      properties:
        already_connected:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Connected
        already_following:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Following
        can_send_message:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Can Send Message
        found_already:
          anyOf:
            - $ref: '#/components/schemas/LinkedInFoundAlready'
            - type: 'null'
        invitation_pending:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Invitation Pending
        kind:
          const: like_latest_post
          default: like_latest_post
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        member_urns:
          items:
            maxLength: 128
            type: string
          maxItems: 8
          title: Member Urns
          type: array
        open_profile:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Open Profile
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        profile_resolved:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Profile Resolved
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        vanity:
          anyOf:
            - type: string
            - type: 'null'
          title: Vanity
      title: LikeLatestPostOutcome
      type: object
    ProfileViewOutcome:
      additionalProperties: false
      description: >-
        What a profile view saw: the common fields and the nine profile facts.


        The view IS the action: LinkedIn records it server-side the moment the
        page

        renders, so ``page_loaded`` is the verification and a view whose facts
        all

        read ``None`` is still a completed view. How long the browser lingered
        and

        how far it scrolled are the driver's pacing, not facts about the member,

        and the row's own ``duration_ms`` already says how long the step took.
      properties:
        already_connected:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Connected
        already_following:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Following
        can_send_message:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Can Send Message
        invitation_pending:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Invitation Pending
        kind:
          const: profile_view
          default: profile_view
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        member_urns:
          items:
            maxLength: 128
            type: string
          maxItems: 8
          title: Member Urns
          type: array
        open_profile:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Open Profile
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        profile_resolved:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Profile Resolved
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        vanity:
          anyOf:
            - type: string
            - type: 'null'
          title: Vanity
      title: ProfileViewOutcome
      type: object
    ReadConversationOutcome:
      additionalProperties: false
      description: >-
        A full reading of one conversation, oldest message first.


        Which thread this was is the step's own ``conversation_id``, on the same

        row; the outcome does not repeat it, so there is no field a settlement

        written without a driver (expiry, restart, a navigation that never
        landed)

        can forget. The read watermark only advances on a ``complete`` reading.
      properties:
        complete:
          default: false
          title: Complete
          type: boolean
        kind:
          const: read_conversation
          default: read_conversation
          title: Kind
          type: string
        messages:
          items:
            $ref: '#/components/schemas/LinkedInMessageRead'
          maxItems: 500
          title: Messages
          type: array
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
      title: ReadConversationOutcome
      type: object
    SendMessageOutcome:
      additionalProperties: false
      description: >-
        What sending a message produced: the common fields, the profile facts
        and the thread.


        ``conversation_urn`` is read off the opened composer when LinkedIn
        exposes

        it, which is the first moment a brand-new thread has an id at all. A
        reply

        into an existing thread happens on the messaging page, where there is no

        profile to read, so the profile facts stay ``None`` there and

        ``member_urn`` is the one the step was given; settlement falls back to
        the

        params' urn for a reply that already knew its thread.
      properties:
        already_connected:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Connected
        already_following:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Following
        can_send_message:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Can Send Message
        conversation_urn:
          anyOf:
            - maxLength: 255
              type: string
            - type: 'null'
          title: Conversation Urn
        found_already:
          anyOf:
            - $ref: '#/components/schemas/LinkedInFoundAlready'
            - type: 'null'
        invitation_pending:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Invitation Pending
        kind:
          const: send_message
          default: send_message
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        member_urns:
          items:
            maxLength: 128
            type: string
          maxItems: 8
          title: Member Urns
          type: array
        open_profile:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Open Profile
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        profile_resolved:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Profile Resolved
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        vanity:
          anyOf:
            - type: string
            - type: 'null'
          title: Vanity
      title: SendMessageOutcome
      type: object
    WithdrawConnectionRequestOutcome:
      additionalProperties: false
      description: >-
        What withdrawing an invitation produced: the common fields and the nine
        profile facts.


        ``invitation_pending`` re-read after the click is the verification. The

        ledger row settles on the params' urn, not on anything read here.
      properties:
        already_connected:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Connected
        already_following:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Already Following
        can_send_message:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Can Send Message
        found_already:
          anyOf:
            - $ref: '#/components/schemas/LinkedInFoundAlready'
            - type: 'null'
        invitation_pending:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Invitation Pending
        kind:
          const: withdraw_connection_request
          default: withdraw_connection_request
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        member_urns:
          items:
            maxLength: 128
            type: string
          maxItems: 8
          title: Member Urns
          type: array
        open_profile:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Open Profile
        page_loaded:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Page Loaded
        profile_resolved:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Profile Resolved
        reason:
          anyOf:
            - $ref: '#/components/schemas/LinkedInSkipReason'
            - type: 'null'
        vanity:
          anyOf:
            - type: string
            - type: 'null'
          title: Vanity
      title: WithdrawConnectionRequestOutcome
      type: object
    CheckConnectionsParams:
      additionalProperties: false
      description: |-
        Housekeeping: read the newest rows of our own connections list.

        ``member_urn`` is the account's member as the server holds it: the exact
        string the browser salts every row key with, and echoes on the outcome.
        ``watermark_keys`` are the keys of the rows the last reading saw, newest
        first, so the browser knows how far back "Show more" needs to go; it may
        press it at most ``max_more`` times. Both are empty and zero on a first
        reading, which is then judged on its first batch alone, and the keys are
        sent only while "Show more" may be pressed at all.
      properties:
        kind:
          const: check_connections
          default: check_connections
          title: Kind
          type: string
        max_more:
          default: 0
          maximum: 5
          minimum: 0
          title: Max More
          type: integer
        member_urn:
          maxLength: 128
          title: Member Urn
          type: string
        watermark_keys:
          items:
            pattern: ^[0-9a-f]{32}$
            type: string
          maxItems: 400
          title: Watermark Keys
          type: array
      required:
        - member_urn
      title: CheckConnectionsParams
      type: object
    CheckInboxParams:
      additionalProperties: false
      description: >-
        Housekeeping: scan the conversation list for new inbound activity. Takes
        nothing.
      properties:
        kind:
          const: check_inbox
          default: check_inbox
          title: Kind
          type: string
      title: CheckInboxParams
      type: object
    CheckSentInvitationsParams:
      additionalProperties: false
      description: 'Housekeeping: read our own sent-invitations list. Takes nothing.'
      properties:
        kind:
          const: check_sent_invitations
          default: check_sent_invitations
          title: Kind
          type: string
      title: CheckSentInvitationsParams
      type: object
    ConnectionRequestParams:
      additionalProperties: false
      description: >-
        Send an invitation, with or without a note.


        ``profile_url`` is where the browser goes first. ``note`` is what the

        browser types, already clipped to LinkedIn's ceiling on a word boundary.

        ``note_original_length`` is how long the rendered note was before
        clipping,

        the one number nothing can recover once the text is gone, so history can

        say who lost text and how much. Whether it was cut follows from the two
        and

        is not stored beside them.
      properties:
        kind:
          const: connection_request
          default: connection_request
          title: Kind
          type: string
        note:
          default: ''
          maxLength: 300
          title: Note
          type: string
        note_original_length:
          default: 0
          minimum: 0
          title: Note Original Length
          type: integer
        profile_url:
          maxLength: 512
          title: Profile Url
          type: string
      required:
        - profile_url
      title: ConnectionRequestParams
      type: object
    FollowContactParams:
      additionalProperties: false
      description: >-
        Follow a member without connecting to them. ``profile_url`` is where the
        browser goes.
      properties:
        kind:
          const: follow_contact
          default: follow_contact
          title: Kind
          type: string
        profile_url:
          maxLength: 512
          title: Profile Url
          type: string
      required:
        - profile_url
      title: FollowContactParams
      type: object
    InMailParams:
      additionalProperties: false
      description: >-
        Send an InMail: a message with a subject line, priced against the
        sender's own credits.


        Addressed exactly like a direct message: a sequence step names the

        contact's profile, an inbox reply names the thread, and the validator

        requires one of the two. ``member_urn`` travels with a thread reply
        because

        the messaging page shows no profile to read it off, and comes back

        unchanged on the outcome.


        The subject has its own, much lower ceiling. Each text carries its
        length

        before clipping under the same rule as every other clipped field.
      properties:
        body:
          maxLength: 1900
          title: Body
          type: string
        body_original_length:
          default: 0
          minimum: 0
          title: Body Original Length
          type: integer
        conversation_urn:
          anyOf:
            - maxLength: 255
              type: string
            - type: 'null'
          title: Conversation Urn
        kind:
          const: inmail
          default: inmail
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        profile_url:
          anyOf:
            - maxLength: 512
              type: string
            - type: 'null'
          title: Profile Url
        subject:
          default: ''
          maxLength: 200
          title: Subject
          type: string
        subject_original_length:
          default: 0
          minimum: 0
          title: Subject Original Length
          type: integer
      required:
        - body
      title: InMailParams
      type: object
    LikeLatestPostParams:
      additionalProperties: false
      description: >-
        Like whatever the member posted most recently, if anything. Starts at
        ``profile_url``.
      properties:
        kind:
          const: like_latest_post
          default: like_latest_post
          title: Kind
          type: string
        profile_url:
          maxLength: 512
          title: Profile Url
          type: string
      required:
        - profile_url
      title: LikeLatestPostParams
      type: object
    ProfileViewParams:
      additionalProperties: false
      description: >-
        Open a member's profile and read it like a person would. The navigation
        is the action.


        ``profile_url`` is where the browser goes first. ``read_relationship``
        asks

        the browser to settle whether the member is connected or has our
        invitation

        pending even where the action bar does not show it, by opening the
        member's

        own More menu and reading it: the look a connection request queues when
        its

        answer cannot be told any other way.
      properties:
        kind:
          const: profile_view
          default: profile_view
          title: Kind
          type: string
        profile_url:
          maxLength: 512
          title: Profile Url
          type: string
        read_relationship:
          default: false
          title: Read Relationship
          type: boolean
      required:
        - profile_url
      title: ProfileViewParams
      type: object
    ReadConversationParams:
      additionalProperties: false
      description: >-
        Housekeeping: open one thread the scan flagged and read it in full.


        ``conversation_id`` names our own row, which is where the reading lands.

        ``conversation_urn`` is LinkedIn's name for the thread and is what the

        browser navigates to; a scan hit with no urn is never queued, because
        there

        is nothing to open. It is still optional for this release only because

        stored rows could not be checked before the deploy: it becomes required

        once a pre-deploy check shows no read_conversation row without one, and

        until then every consumer keeps handling None. The member's own urn is
        not

        carried: it already sits on the row this id names, and neither the
        browser

        nor the service ever read the copy.
      properties:
        conversation_id:
          format: uuid
          title: Conversation Id
          type: string
        conversation_urn:
          anyOf:
            - maxLength: 255
              type: string
            - type: 'null'
          title: Conversation Urn
        kind:
          const: read_conversation
          default: read_conversation
          title: Kind
          type: string
      required:
        - conversation_id
      title: ReadConversationParams
      type: object
    SendMessageParams:
      additionalProperties: false
      description: >-
        Send a direct message, either from a profile or into an existing thread.


        Two producers disagree about where a message goes, and both are right: a

        sequence step knows only the contact's profile, while a reply from the

        Oneprofile inbox knows the thread and not the profile. Rather than make

        every field optional and hope, the validator requires at least one
        usable

        target. ``member_urn`` travels with a thread reply because the messaging

        page shows no profile to read it off; the browser hands it back
        unchanged

        as the outcome's ``member_urn``, which is what the conversation row is

        keyed on.


        ``body_original_length`` follows the rule ``note_original_length`` sets
        on

        a connection request: the body was cut exactly when it is longer than

        ``body``.
      properties:
        body:
          maxLength: 8000
          title: Body
          type: string
        body_original_length:
          default: 0
          minimum: 0
          title: Body Original Length
          type: integer
        conversation_urn:
          anyOf:
            - maxLength: 255
              type: string
            - type: 'null'
          title: Conversation Urn
        kind:
          const: send_message
          default: send_message
          title: Kind
          type: string
        member_urn:
          anyOf:
            - maxLength: 128
              type: string
            - type: 'null'
          title: Member Urn
        profile_url:
          anyOf:
            - maxLength: 512
              type: string
            - type: 'null'
          title: Profile Url
      required:
        - body
      title: SendMessageParams
      type: object
    WithdrawConnectionRequestParams:
      additionalProperties: false
      description: |-
        Withdraw an invitation this sender already sent.

        ``profile_url`` is where the browser goes first. ``member_urn`` is
        required, unlike everywhere else: the ledger row is keyed on it, the
        dispatcher read it off that row when it decided to withdraw, and
        settlement closes the row by it.
      properties:
        kind:
          const: withdraw_connection_request
          default: withdraw_connection_request
          title: Kind
          type: string
        member_urn:
          maxLength: 128
          title: Member Urn
          type: string
        profile_url:
          maxLength: 512
          title: Profile Url
          type: string
      required:
        - profile_url
        - member_urn
      title: WithdrawConnectionRequestParams
      type: object
    LinkedInSkipReason:
      description: >-
        The specific reason a step was not applicable, when the driver knows
        one.


        Narrower than the error code beside it: ``not_applicable`` says the step

        could not apply, and this says why in a way a customer can act on. An

        invitation already pending is their own earlier work, while "connect not

        offered" is LinkedIn's decision about that profile.
      enum:
        - invitation_already_pending
        - connect_not_offered
        - email_required
        - message_not_offered
        - no_invitation_pending
        - already_connected
        - profile_not_resolved
        - vanity_changed
      title: LinkedInSkipReason
      type: string
    LinkedInConnectionRow:
      additionalProperties: false
      description: >-
        One row of a connections reading, newest first, as keys only.


        ``keys`` spell the member the row names: its vanity, and any URN that
        was

        cross-checked against it, each hashed (see
        ``CONNECTION_ROW_KEY_PATTERN``).

        A row that named nobody the reading could trust has no keys, and keeps
        its

        place, because where an unread row sits decides whether the reading
        proves

        that nothing was missed.
      properties:
        keys:
          items:
            pattern: ^[0-9a-f]{32}$
            type: string
          maxItems: 4
          title: Keys
          type: array
      title: LinkedInConnectionRow
      type: object
    LinkedInConversationRow:
      additionalProperties: false
      description: One row of the message-list scan, as the agent read it off the page.
      properties:
        conversation_urn:
          anyOf:
            - maxLength: 255
              type: string
            - type: 'null'
          title: Conversation Urn
        last_activity_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Last Activity At
        last_inbound_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Last Inbound At
        member_urn:
          maxLength: 128
          title: Member Urn
          type: string
        snippet:
          default: ''
          maxLength: 200
          title: Snippet
          type: string
      required:
        - member_urn
      title: LinkedInConversationRow
      type: object
    LinkedInFoundAlready:
      description: >-
        Why a step that changes LinkedIn found its change already there, and
        settled succeeded.


        Only for a step whose own earlier attempt may have made it: the server
        had

        granted that attempt the press. A change already there with no grant
        ever

        was made outside Oneprofile, and settles skipped ("already pending" and
        so

        on), uncharged.
      enum:
        - earlier_attempt
      title: LinkedInFoundAlready
      type: string
    LinkedInMessageRead:
      additionalProperties: false
      description: One message read out of an opened conversation.
      properties:
        body_text:
          default: ''
          maxLength: 8000
          title: Body Text
          type: string
        is_inbound:
          title: Is Inbound
          type: boolean
        message_urn:
          maxLength: 255
          title: Message Urn
          type: string
        sender_member_urn:
          maxLength: 128
          title: Sender Member Urn
          type: string
        sender_name:
          default: ''
          maxLength: 255
          title: Sender Name
          type: string
        sent_at:
          anyOf:
            - format: date-time
              type: string
            - type: 'null'
          title: Sent At
      required:
        - message_urn
        - sender_member_urn
        - is_inbound
      title: LinkedInMessageRead
      type: object
  securitySchemes:
    APIKeyHeader:
      in: header
      name: X-API-Key
      type: apiKey

````

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