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

# Connect a destination

> Authorize a provider account and create a Destination ID for publishing.

Use a connection session to authorize a provider account. OpenPMM stores the provider credential. Your application receives a destination ID.

<Steps>
  <Step title="Choose a provider">
    Use `bluesky`, `x`, `youtube`, `facebook`, `instagram`, `threads`, `mastodon`, `linkedin`, or `tiktok`. This enum is part of the connection-session request. OpenPMM does not provide a separate provider-catalog endpoint.

    During the beta, some providers are not connectable yet in every deployment. A connection session for a provider that is not available fails with a `destination_unavailable` error rather than returning a pending session.

    For Mastodon, also send the instance origin. For Bluesky, also send the account handle or DID.
  </Step>

  <Step title="Connect Bluesky">
    Bluesky OAuth requires the hosted OpenPMM service with its HTTPS public URL. A local HTTP development origin cannot act as this confidential OAuth client.
    Set `account_identifier` to the handle or DID that must authorize OpenPMM. The DID becomes the stable destination identity. A handle change does not create a new destination.

    ```bash theme={null}
    openpmm destinations connect \
      --workspace "$OPENPMM_WORKSPACE_ID" \
      --provider bluesky \
      --account alice.bsky.social
    ```
  </Step>

  <Step title="Create a connection session">
    Send the provider to the connection-session endpoint.

    ```bash theme={null}
    curl --request POST \
      --url "https://api.openpmm.com/v1/workspaces/$OPENPMM_WORKSPACE_ID/destination-connection-sessions" \
      --header "Authorization: Bearer $OPENPMM_API_KEY" \
      --header "Content-Type: application/json" \
      --header "Idempotency-Key: $(uuidgen)" \
      --data '{"provider":"linkedin"}'
    ```
  </Step>

  <Step title="Open the authorization URL">
    Open the returned `authorization_url` in a browser. A person must complete this step. Do not open the URL in an unattended worker.
  </Step>

  <Step title="Check the connection status">
    Save the returned session `id`. Get the session until its status is `completed`, `failed`, or `expired`.

    ```bash theme={null}
    export OPENPMM_CONNECTION_SESSION_ID="your_connection_session_id"

    curl --request GET \
      --url "https://api.openpmm.com/v1/workspaces/$OPENPMM_WORKSPACE_ID/destination-connection-sessions/$OPENPMM_CONNECTION_SESSION_ID" \
      --header "Authorization: Bearer $OPENPMM_API_KEY"
    ```
  </Step>

  <Step title="Get the destination ID">
    After the session is complete, list the connected publishing targets. Store the new destination ID.

    ```bash theme={null}
    curl --request GET \
      --url "https://api.openpmm.com/v1/workspaces/$OPENPMM_WORKSPACE_ID/destinations" \
      --header "Authorization: Bearer $OPENPMM_API_KEY"
    ```

    The response is `{"data":[]}` when the Workspace has no connected publishing targets. This endpoint does not use pagination.
  </Step>
</Steps>

<Note>
  OpenPMM does not return provider credentials to your application. It stores OAuth tokens and Bluesky DPoP session keys in encrypted form.
</Note>
