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

# Get Workspace and Key

> Inspect the authenticated workspace, subscription, effective scopes, expiry, and rate limits.

Requires `workspace:read`. Start here to verify which workspace the key belongs to and what it can do.

The response contains `workspace`, `subscription`, `apiKey` and `missingScopes`. `apiKey.scopes` includes implied scopes and the creator's current permission cap; `fullAccess` identifies a key created without an explicit scope list. It does not override membership, billing or operation-specific permissions.

This response does not expose the raw key. `subscription.active` is REST subscription information, not proof that MCP access is enabled.


## OpenAPI

````yaml GET /v1/me
openapi: 3.0.0
info:
  title: SendPilot External API
  description: >

    # SendPilot External API v1


    Public API for integrating with SendPilot programmatically.


    ## Authentication


    Requests authenticate with a workspace API key in the `X-API-Key` header:


    ```

    X-API-Key: sp_live_your_api_key_here

    ```


    `Authorization: Bearer sp_live_...` (or `sp_test_...`) is also accepted.
    Prefer one header; `X-API-Key` takes precedence. Clerk OAuth tokens for MCP
    connection URLs are not public REST API keys.


    A key only reaches what its scopes and creator's current workspace
    permissions allow. Each operation lists the scopes it needs in
    `x-sp-scopes`. Use `GET /v1/me` to inspect the effective permissions and
    subscription state.


    ## Rate Limits


    - **Per API Key**: 300 requests/minute

    - **Per Workspace**: 50,000 requests/day


    Responses that reach the rate limiter include these headers; early
    authentication failures may not:

    - `X-RateLimit-Limit`: Max requests per minute

    - `X-RateLimit-Remaining`: Remaining requests in current window

    - `X-RateLimit-Reset`: Epoch timestamp when limit resets


    ## LinkedIn Sender Limits


    When using messaging endpoints, these headers show account limits:

    - `X-LinkedIn-Messages-Remaining`: Messages left today

    - `X-LinkedIn-Connections-Remaining`: Connection requests left today

    - `X-LinkedIn-Quota-Reset-At`: When daily limits reset


    ## Retries


    Send an `Idempotency-Key` header on POST and PATCH requests. A retry with
    the same key within 24 hours returns the first result (with
    `Idempotent-Replayed: true`) instead of acting twice. The same key with a
    different request answers 422 `IDEMPOTENCY_KEY_REUSED`; a retry while the
    first request still runs answers 409 `IDEMPOTENCY_IN_PROGRESS`.


    Once execution is attempted, its response (including errors) is retained. If
    a process stops or result storage fails after the attempt, the durable
    record blocks another execution for the replay window and returns 409
    `IDEMPOTENCY_IN_PROGRESS` or `IDEMPOTENCY_REPLAY_UNAVAILABLE`. Check the
    operation's status before using a new key: an uncertain outcome may already
    have acted. Requests refused before execution is claimed, such as
    authentication or rate-limit refusals, can be retried with the same key.


    ## Webhooks


    Configure webhooks in the SendPilot app to receive real-time events:

    - `lead.tag.updated`

    - `lead.updated`

    - `message.sent`

    - `reply.received`

    - `connection_request.sent`

    - `connection_request.accepted`

    - `campaign.started`

    - `campaign.paused`

    - `campaign.resumed`

    - `campaign.finished`


    ## Error Codes


    Errors return a JSON body. Use the machine-readable `code` when supplied;
    validation messages can be arrays, and some legacy errors omit `code`. A
    typical error is:

    ```json

    {
      "statusCode": 400,
      "error": "Bad Request",
      "code": "SPECIFIC_ERROR_CODE",
      "message": "Human-readable description"
    }

    ```
  version: '1.0'
  contact:
    name: SendPilot Support
    url: https://sendpilot.ai
    email: support@sendpilot.ai
servers:
  - url: https://api.sendpilot.ai
security: []
tags: []
paths:
  /v1/me:
    get:
      tags:
        - External API - Workspace
      summary: Get the calling API key and its workspace
      description: >-
        Returns the workspace, whether its subscription is active, and the API
        key's scopes, expiry and rate limits.
      operationId: workspace.me
      parameters: []
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MeResponseDto'
        '401':
          description: Invalid or missing API key
        '403':
          description: Key lacks workspace:read
      security:
        - api-key: []
components:
  schemas:
    MeResponseDto:
      type: object
      properties:
        workspace:
          $ref: '#/components/schemas/MeWorkspaceDto'
        subscription:
          $ref: '#/components/schemas/MeSubscriptionDto'
        apiKey:
          $ref: '#/components/schemas/MeApiKeyDto'
        missingScopes:
          type: array
          description: Scopes the key would need for full access
          items:
            type: string
            enum:
              - workspace:read
              - campaigns:read
              - campaigns:write
              - leads:read
              - leads:write
              - inbox:read
              - inbox:send
              - senders:read
              - senders:manage
              - lead_sourcing:run
              - credits:read
              - webhooks:read
              - webhooks:manage
              - content:read
              - content:write
      required:
        - workspace
        - subscription
        - apiKey
        - missingScopes
    MeWorkspaceDto:
      type: object
      properties:
        id:
          type: string
          example: ws_123
        name:
          type: string
          example: Acme Outbound
        active:
          type: boolean
          description: False once the workspace is deactivated
      required:
        - id
        - name
        - active
    MeSubscriptionDto:
      type: object
      properties:
        active:
          type: boolean
          description: >-
            False when the subscription has lapsed: reads still work, changes
            return 402 SUBSCRIPTION_INACTIVE
      required:
        - active
    MeApiKeyDto:
      type: object
      properties:
        id:
          type: string
          example: key_123
        name:
          type: string
          example: Claude agent (read-only)
        scopes:
          type: array
          description: What the key may do, including implied scopes
          items:
            type: string
            enum:
              - workspace:read
              - campaigns:read
              - campaigns:write
              - leads:read
              - leads:write
              - inbox:read
              - inbox:send
              - senders:read
              - senders:manage
              - lead_sourcing:run
              - credits:read
              - webhooks:read
              - webhooks:manage
              - content:read
              - content:write
        fullAccess:
          type: boolean
          description: True for keys created without scopes
        expiresAt:
          format: date-time
          type: string
          description: When the key stops working
        rateLimits:
          $ref: '#/components/schemas/MeRateLimitsDto'
      required:
        - id
        - name
        - scopes
        - fullAccess
        - rateLimits
    MeRateLimitsDto:
      type: object
      properties:
        perMinute:
          type: number
          example: 300
        perDay:
          type: number
          example: 50000
      required:
        - perMinute
        - perDay
  securitySchemes:
    api-key:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'API key for authentication (prefix: sp_live_ or sp_test_)'

````