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

# Get Publication

> Retrieve a single publication by its id, including its per-platform posts, analytics, and aggregated totals

# Get Publication

Retrieve one publication by its **publication id** — the `id` returned by
[List Published Projects](/api-reference/list-published-projects). A publication
represents one publish event for a project and contains a `posts` array with one
entry per platform. The response includes per-platform delivery status, post
URLs, analytics, and a `totals` rollup aggregated across those posts.

<Note>
  This endpoint requires authentication.
</Note>

<Info>
  The `{id}` is the **publication id** (the `id` field from List Published
  Projects), **not** a project id. A single project can be published multiple
  times, so each publication has its own id. The `projectId` is still returned
  for linking back to the underlying project.
</Info>

## Authentication

<ParamField header="x-api-key" type="string" required>
  Your Submagic API key starting with `sk-`
</ParamField>

## Path Parameters

<ParamField path="id" type="string" required>
  The unique identifier (UUID) of the publication to retrieve
</ParamField>

## Response

<ResponseField name="id" type="string">
  Unique identifier of the publication
</ResponseField>

<ResponseField name="projectId" type="string">
  The unique identifier of the underlying project
</ResponseField>

<ResponseField name="publishedAt" type="string">
  ISO 8601 timestamp of when the publication was published or is scheduled to
  publish
</ResponseField>

<ResponseField name="scheduled" type="boolean">
  `true` if the publication was scheduled for a future time
</ResponseField>

<ResponseField name="status" type="string">
  Overall publication status: `published`, `scheduled`, `processing`, or
  `failed`
</ResponseField>

<ResponseField name="project" type="object">
  Minimal project metadata

  <Expandable title="Project">
    <ResponseField name="id" type="string">
      Project UUID
    </ResponseField>

    <ResponseField name="title" type="string">
      Project title
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="totals" type="object">
  Metrics aggregated across the publication's platforms

  <Expandable title="Totals">
    <ResponseField name="views" type="number">
      Sum of views across all platforms
    </ResponseField>

    <ResponseField name="engagement" type="number">
      Sum of likes, comments, and shares across all platforms
    </ResponseField>

    <ResponseField name="followersGained" type="number">
      Net followers gained around the publish time, summed across the
      publication's accounts. `null` when no follower snapshots are available
      to compute the delta.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="posts" type="array">
  Array of per-platform post objects

  <Expandable title="Post Object">
    <ResponseField name="platform" type="string">
      Platform identifier: `youtube`, `tiktok`, `instagram`, `twitter`,
      `facebook`, or `linkedin`
    </ResponseField>

    <ResponseField name="platformPostId" type="string">
      The post ID assigned by the upstream platform
    </ResponseField>

    <ResponseField name="platformPostUrl" type="string">
      Public URL of the post on the platform
    </ResponseField>

    <ResponseField name="publishStatus" type="string">
      Per-platform delivery status: `published`, `scheduled`, `processing`, or
      `failed`
    </ResponseField>

    <ResponseField name="syncStatus" type="string">
      Analytics sync status: `synced`, `pending`, or `failed`
    </ResponseField>

    <ResponseField name="error" type="string">
      Error message if the post failed to publish, otherwise `null`
    </ResponseField>

    <ResponseField name="analytics" type="object">
      Platform analytics (available once `syncStatus` is `synced`)

      <Expandable title="Analytics">
        <ResponseField name="views" type="number">
          Total views
        </ResponseField>

        <ResponseField name="likes" type="number">
          Total likes
        </ResponseField>

        <ResponseField name="comments" type="number">
          Total comments
        </ResponseField>

        <ResponseField name="shares" type="number">
          Total shares
        </ResponseField>

        <ResponseField name="impressions" type="number">
          Total impressions
        </ResponseField>

        <ResponseField name="reach" type="number">
          Unique accounts reached
        </ResponseField>

        <ResponseField name="clicks" type="number">
          Total link clicks
        </ResponseField>

        <ResponseField name="engagementRate" type="number">
          Engagement rate as a decimal (e.g. `0.125` = 12.5%)
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://api.submagic.co/v1/projects/published/pub_8f3b4c2e-1a9d-4e5f-9b7c-2a4d6e8f1c3b" \
    -H "x-api-key: sk-your-api-key-here"
  ```

  ```javascript JavaScript theme={null}
  const getPublication = async (publicationId) => {
    const response = await fetch(
      `https://api.submagic.co/v1/projects/published/${publicationId}`,
      {
        headers: {
          "x-api-key": "sk-your-api-key-here",
        },
      }
    );

    return response.json();
  };

  const publication = await getPublication(
    "pub_8f3b4c2e-1a9d-4e5f-9b7c-2a4d6e8f1c3b"
  );
  console.log(
    `${publication.totals.views} views across ${publication.posts.length} platforms`
  );
  ```

  ```python Python theme={null}
  import requests

  def get_publication(publication_id):
      url = f'https://api.submagic.co/v1/projects/published/{publication_id}'
      headers = {
          'x-api-key': 'sk-your-api-key-here'
      }
      response = requests.get(url, headers=headers)
      return response.json()

  publication = get_publication('pub_8f3b4c2e-1a9d-4e5f-9b7c-2a4d6e8f1c3b')
  print(f"{publication['totals']['views']} views across "
        f"{len(publication['posts'])} platforms")
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "id": "pub_8f3b4c2e-1a9d-4e5f-9b7c-2a4d6e8f1c3b",
    "projectId": "550e8400-e29b-41d4-a716-446655440000",
    "publishedAt": "2026-04-28T12:34:56.000Z",
    "scheduled": false,
    "status": "published",
    "project": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "title": "How I Doubled My Revenue in 30 Days"
    },
    "totals": {
      "views": 1234,
      "engagement": 65,
      "followersGained": 18
    },
    "posts": [
      {
        "platform": "youtube",
        "platformPostId": "dQw4w9WgXcQ",
        "platformPostUrl": "https://youtube.com/watch?v=dQw4w9WgXcQ",
        "publishStatus": "published",
        "syncStatus": "synced",
        "error": null,
        "analytics": {
          "views": 1234,
          "likes": 56,
          "comments": 7,
          "shares": 2,
          "impressions": 5000,
          "reach": 800,
          "clicks": 120,
          "engagementRate": 0.125
        }
      }
    ]
  }
  ```
</ResponseExample>

## Error Responses

<ResponseField name="404 Not Found" type="object">
  ```json theme={null}
  {
    "error": "NOT_FOUND",
    "message": "Publication not found"
  }
  ```
</ResponseField>

<ResponseField name="401 Unauthorized" type="object">
  ```json theme={null}
  {
    "error": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
  ```
</ResponseField>

<ResponseField name="429 Rate Limited" type="object">
  ```json theme={null}
  {
    "error": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests",
    "retryAfter": 30
  }
  ```
</ResponseField>

<ResponseField name="500 Server Error" type="object">
  ```json theme={null}
  {
    "error": "INTERNAL_SERVER_ERROR",
    "message": "An unexpected error occurred"
  }
  ```
</ResponseField>
