# Getting Started

Publish your first post to one or more social networks with a single API request.


Relaycast is one REST API and dashboard for publishing to X (Twitter), Instagram, Facebook, LinkedIn, TikTok, YouTube, Threads, Pinterest, Bluesky and Google Business Profile. You connect accounts once, then send one request that fans out to every account you choose. Each platform succeeds or fails on its own, and you can read the result per platform.

This guide takes about five minutes. You will:

1. Create an access key
2. Connect a social account
3. List your accounts to get an account ID
4. Publish your first post
5. Schedule a post for later

All API requests go to `https://social-publish-api.onrender.com` and send and receive JSON.

## 1. Create an access key

Open **Access Keys** in the dashboard at [https://social-publish-kappa.vercel.app/dashboard/api-keys](https://social-publish-kappa.vercel.app/dashboard/api-keys), click **Create key** and give it a name (for example `production` or `local-dev`).

Copy the key right away. It starts with `sp_live_` and is shown only once, because Relaycast stores only a hash of it.

> [!WARNING]
> An access key can publish to every account in its project. Keep it on your server, never in browser or mobile code, and revoke it from the Access Keys page if it leaks.

Store it in an environment variable so the examples below work as written:

```bash
export RELAYCAST_API_KEY="sp_live_..."
```

See [Authentication](/docs/authentication) for header options and key management.

## 2. Connect a social account

Open **Integrations** at [https://social-publish-kappa.vercel.app/dashboard/integrations](https://social-publish-kappa.vercel.app/dashboard/integrations), click **New integration** and pick a platform. You'll be sent to the platform's consent screen and returned to the dashboard when the account is connected.

> [!NOTE]
> OAuth platforms (everything except Bluesky) are connected in the dashboard, or by your own users through a [connect link](/docs/api/create-connect-link). Bluesky can also be connected through the API with an app password, see [Connect Bluesky](/docs/api/connect-bluesky).

Each platform has its own requirements, such as Instagram needing a professional account or TikTok needing a privacy level on every post. Check the [platform guides](/docs/platforms) before you publish.

## 3. List your accounts

Every post targets accounts by their Relaycast ID. Fetch them with `GET /v1/accounts`:

```bash tab="cURL"
curl https://social-publish-api.onrender.com/v1/accounts \
  -H "x-access-key: $RELAYCAST_API_KEY"
```

```ts tab="Node.js"
const res = await fetch("https://social-publish-api.onrender.com/v1/accounts", {
  headers: { "x-access-key": process.env.RELAYCAST_API_KEY! },
});
const { data: accounts } = await res.json();
console.log(accounts);
```

```python tab="Python"
import os
import requests

res = requests.get(
    "https://social-publish-api.onrender.com/v1/accounts",
    headers={"x-access-key": os.environ["RELAYCAST_API_KEY"]},
)
print(res.json()["data"])
```

The response lists every connected account:

```json
{
  "data": [
    {
      "id": "8f1c2a4e-5b6d-4e7f-9a0b-1c2d3e4f5a6b",
      "platform": "linkedin",
      "handle": "jane-doe",
      "displayName": "Jane Doe",
      "avatarUrl": "https://...",
      "status": "active",
      "groupId": null,
      "oauthAppId": null,
      "createdAt": "2026-09-30T10:12:00.000Z"
    }
  ]
}
```

Copy the `id` of the account you want to post to. You can also copy it from the Integrations page. Only accounts with `status: "active"` can be published to. See [Social Accounts](/docs/social-accounts) for the other statuses.

## 4. Publish your first post

Send `POST /v1/posts` with your text, the target accounts and `publishNow: true`:

```bash tab="cURL"
curl -X POST https://social-publish-api.onrender.com/v1/posts \
  -H "x-access-key: $RELAYCAST_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: first-post-001" \
  -d '{
    "content": "Hello from Relaycast!",
    "targets": [{ "accountId": "8f1c2a4e-5b6d-4e7f-9a0b-1c2d3e4f5a6b" }],
    "publishNow": true
  }'
```

```ts tab="Node.js"
const res = await fetch("https://social-publish-api.onrender.com/v1/posts", {
  method: "POST",
  headers: {
    "x-access-key": process.env.RELAYCAST_API_KEY!,
    "Content-Type": "application/json",
    "Idempotency-Key": "first-post-001",
  },
  body: JSON.stringify({
    content: "Hello from Relaycast!",
    targets: [{ accountId: "8f1c2a4e-5b6d-4e7f-9a0b-1c2d3e4f5a6b" }],
    publishNow: true,
  }),
});
const { data: post } = await res.json();
console.log(post.id, post.status);
```

```python tab="Python"
import os
import requests

res = requests.post(
    "https://social-publish-api.onrender.com/v1/posts",
    headers={
        "x-access-key": os.environ["RELAYCAST_API_KEY"],
        "Idempotency-Key": "first-post-001",
    },
    json={
        "content": "Hello from Relaycast!",
        "targets": [{"accountId": "8f1c2a4e-5b6d-4e7f-9a0b-1c2d3e4f5a6b"}],
        "publishNow": True,
    },
)
post = res.json()["data"]
print(post["id"], post["status"])
```

A `201 Created` response means the post was validated for every target, credits were reserved, and publishing has been queued. Publishing itself happens in the background, so check the result with `GET /v1/posts/{id}`:

```bash
curl https://social-publish-api.onrender.com/v1/posts/POST_ID -H "x-access-key: $RELAYCAST_API_KEY"
```

Each entry in `targets` has its own `status` (`queued`, `publishing`, `published` or `failed`), plus `externalUrl` once it's live or `errorMessage` if it failed. The post's overall `status` becomes `published`, `partial` or `failed` when every target is done.

> [!TIP]
> Rather than polling, set up a [webhook notification](/docs/notifications) for `post.published`, `post.partial` and `post.failed`.

## 5. Schedule a post

To publish later, leave out `publishNow` and send `scheduledFor` as an ISO 8601 timestamp with a timezone offset:

```bash tab="cURL"
curl -X POST https://social-publish-api.onrender.com/v1/posts \
  -H "x-access-key: $RELAYCAST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Our launch is live!",
    "targets": [
      { "accountId": "8f1c2a4e-5b6d-4e7f-9a0b-1c2d3e4f5a6b" },
      { "accountId": "2b7d9e1f-3a4c-4d5e-8f6a-7b8c9d0e1f2a" }
    ],
    "media": [{ "url": "https://example.com/launch.jpg", "type": "image", "altText": "Product screenshot" }],
    "scheduledFor": "2026-10-12T09:00:00-04:00"
  }'
```

```ts tab="Node.js"
await fetch("https://social-publish-api.onrender.com/v1/posts", {
  method: "POST",
  headers: { "x-access-key": process.env.RELAYCAST_API_KEY!, "Content-Type": "application/json" },
  body: JSON.stringify({
    content: "Our launch is live!",
    targets: [
      { accountId: "8f1c2a4e-5b6d-4e7f-9a0b-1c2d3e4f5a6b" },
      { accountId: "2b7d9e1f-3a4c-4d5e-8f6a-7b8c9d0e1f2a" },
    ],
    media: [{ url: "https://example.com/launch.jpg", type: "image", altText: "Product screenshot" }],
    scheduledFor: "2026-10-12T09:00:00-04:00",
  }),
});
```

```python tab="Python"
requests.post(
    "https://social-publish-api.onrender.com/v1/posts",
    headers={"x-access-key": os.environ["RELAYCAST_API_KEY"]},
    json={
        "content": "Our launch is live!",
        "targets": [
            {"accountId": "8f1c2a4e-5b6d-4e7f-9a0b-1c2d3e4f5a6b"},
            {"accountId": "2b7d9e1f-3a4c-4d5e-8f6a-7b8c9d0e1f2a"},
        ],
        "media": [{"url": "https://example.com/launch.jpg", "type": "image", "altText": "Product screenshot"}],
        "scheduledFor": "2026-10-12T09:00:00-04:00",
    },
)
```

The post is created with `status: "scheduled"` and publishes at that time. Media URLs must be publicly reachable, see [Media & Uploads](/docs/media).

## Next steps

- [Core Concepts](/docs/core-concepts): projects, accounts, posts, targets and credits
- [Posts](/docs/posts): the full request body, per-account content and statuses
- [Platform Options](/docs/platform-options): titles, privacy levels, boards and other platform settings
- [Playground](/docs/playground): build and test requests visually in the dashboard
- [API Reference](/docs/api): every endpoint in detail
