Plans & Limits

Cloud-edition plan tiers, hard limits, add-ons, and pay-as-you-go pricing. Self-hosted has no limits.

Posthawk Cloud has three plan tiers. Limits are enforced server-side on the resource APIs (POST /v1/contacts is checked against `maxContacts`, etc.) — exceeding a limit returns a 403 with the current plan name and the limit that was hit.

Self-hosted is feature-flagged separately and has no limits or billing.

Plan limits (cloud):

| Limit | Free | Pro | Scale |
|-------|------|-----|------------|
| Emails / month | 3,000 | 50,000 | 100,000 |
| Emails / day | 100 | Unlimited | Unlimited |
| Domains | 1 | 10 | 100 |
| API keys | 2 | 25 | 100 |
| Team members | 2 | 10 | 50 |
| Workspaces | 1 | 3 | 10 |
| Templates | 3 | 10 | Unlimited |
| Webhook endpoints | 1 | 5 | Unlimited |
| Contacts | 1,000 | 25,000 | Unlimited |
| Max email size | 10 MB | 30 MB | 30 MB |
| Log retention | 3 days | 15 days | 30 days |
| Workflow automations | — | — | ✓ |
| AI assistant | — | — | ✓ |
| Audit logs | — | — | ✓ |
| Pay-as-you-go overages | — | ✓ | ✓ |

Pay-as-you-go overages:

Pro and Scale plans can opt into pay-as-you-go for emails sent beyond the included monthly volume. Overage is billed at $0.60 per 1,000 emails (rounded up to the nearest block). Free plan cannot enable PAYG — they hit a hard cap at 3,000.

Add-ons (cloud):

• Extra team member — $6/month per seat (up to 100 total members hard cap)
• Extra workspace — $6/month per slot (up to 20 total workspaces hard cap)

When you hit a limit, the API returns:

```json
{
  "error": "Plan limit reached",
  "code": "plan_limit_reached",
  "message": "Free plan allows up to 1 domain. Upgrade to Pro to add more.",
  "currentPlan": "free",
  "limit": "maxDomains",
  "currentValue": 1,
  "maxValue": 1
}
```

Workspace plan info (and live usage) is available via `GET /api/settings/usage` from the dashboard.
GET/api/settings/usageJWT

Get the workspace's current plan, subscription state, live usage across all metered resources, add-ons, effective limits (base + add-ons), pay-as-you-go state, and AI usage. Used by the dashboard usage tab and several enforcement checks.

Response

json
{
  "plan": { "name": "pro", "max_emails_per_month": 50000, "max_domains": 10, ... },
  "subscription": {
    "id": "sub-uuid",
    "status": "active",
    "current_period_start": "2026-04-01T00:00:00Z",
    "current_period_end": "2026-05-01T00:00:00Z"
  },
  "usage": {
    "emailsThisMonth": 12450,
    "emailsToday": 412,
    "domains": 4,
    "apiKeys": 8,
    "teamMembers": 5,
    "inboundEmailsThisMonth": 230,
    "storageBytesUsed": 1840000,
    "templates": 6,
    "webhooks": 2
  },
  "payAsYouGo": {
    "enabled": true,
    "overage": 0,
    "overageBlocks": 0,
    "overageCostCents": 0
  },
  "addons": {
    "extraTeamMembers": 0,
    "extraWorkspaces": 0,
    "unitPriceCents": 600
  },
  "effectiveLimits": {
    "maxTeamMembers": 10,
    "maxWorkspaces": 3
  }
}
PATCH/api/settings/pay-as-you-goJWT

Toggle pay-as-you-go billing for the workspace. Only available on paid plans (Pro, Scale) — free plan returns 403. After enabling, sends beyond the monthly quota are billed at $0.60 per 1,000 emails, rounded up to the nearest block.

ParameterTypeInDescription
enabledrequiredbooleanbodytrue to enable PAYG, false to disable (sends past quota will be rejected with quota_exceeded)

Request

bash
curl -X PATCH https://app.posthawk.dev/api/settings/pay-as-you-go \
  -H "Content-Type: application/json" \
  -H "Cookie: sb-...=..." \
  -d '{ "enabled": true }'

Response

json
{
  "success": true,
  "payAsYouGo": { "enabled": true }
}