# Credits & Usage

How publishing and analytics use credits, when credits are refunded, and how to track usage.


Relaycast meters usage with **credits**. Each project has its own credit balance, shown in the dashboard sidebar and on the **Usage** page.

## What costs credits

| Action | Cost |
| --- | --- |
| Publishing a post | **1 credit per target** (per account the post goes to) |
| Loading post analytics | **1 credit per load**, for the whole post |
| Everything else | Free |

A post sent to one LinkedIn profile, one X account and one Instagram account costs 3 credits, whether it publishes now or is scheduled. Free actions include listing accounts, reading posts, validating drafts in the Playground, viewing cached analytics, the Inbox and comment automations, webhooks and logs.

## When credits are charged

Credits for a post are charged **when the post is created**, before anything is queued. This includes scheduled posts: a post scheduled for next week uses its credits today.

Credits are charged only after validation passes. A request rejected with `400` (for example invalid content or an unknown account) costs nothing. A replay with the same `Idempotency-Key` costs nothing either, see [Idempotency & Retries](/docs/idempotency).

## Refunds

Credits come back automatically when work doesn't happen:

- **Failed targets.** When a target fails for good, after any retries, its 1 credit is refunded. A `partial` post is only charged for the targets that published.
- **Deleted posts.** Deleting a post from the **Posts** page cancels targets that haven't published yet and refunds them. Targets that already published stay charged.
- **Empty analytics loads.** If loading analytics can't fetch numbers from any platform, the credit is refunded.

Each refund is applied once, even if the same target is processed more than once.

## Insufficient credits

If the balance can't cover the whole post, the request fails with `402` and nothing is created:

```json
{
  "error": {
    "code": "insufficient_credits",
    "message": "This post needs 3 credits"
  }
}
```

Posts are all-or-nothing: Relaycast doesn't publish to some targets and skip the rest. Reduce the number of targets or add credits, then retry. Retrying with the same `Idempotency-Key` is safe, because a rejected request isn't stored.

There's no API endpoint for the credit balance. If you need to check it from code, handle `402` and alert on it.

## Plans

Every project is on the **Free** plan with **20 credits a month**. Credits renew at the start of each calendar month (UTC): the balance is topped back up to 20. Renewal never lowers a balance, so any credits above 20 are kept. The billing tab under **Settings → Billing** at [https://social-publish-kappa.vercel.app/dashboard/settings?tab=billing](https://social-publish-kappa.vercel.app/dashboard/settings?tab=billing) shows the plan and how many credits are left. Paid plans aren't available yet; see [Pricing](/pricing).

## Usage page

**Usage** at [https://social-publish-kappa.vercel.app/dashboard/usage](https://social-publish-kappa.vercel.app/dashboard/usage) shows:

- credits left,
- posts created in the last 30 days,
- published and failed targets in the last 30 days,
- the **credit history**: every charge and refund, newest first.

## Usage emails

Project owners and admins receive emails when credits run low:

| Email | Sent when |
| --- | --- |
| Monthly plan credits | 80% of the plan's credits are used. |
| Monthly credits used up | The balance reaches zero. |

Each email is sent once when its threshold is crossed, and the alerts reset when credits renew each month. If credits recover above the threshold (for example after refunds), it can be sent again the next time it's crossed. Turn either email off under **Settings → General**.

> [!NOTE]
> Usage emails need an email provider configured on the deployment. The settings page tells you if email isn't set up.

## Related

- [Rate Limits](/docs/limits) for request limits, which are separate from credits
- [Errors](/docs/errors)
- [Analytics](/docs/analytics)
