Skip to main content

System Webhooks

Notify your own services about what happens across the whole instance: new users and workspaces, subscription changes, payments, trials and the first steps customers take.

Overview​

Webhooks created in a workspace only hear about that workspace: its posts and its social accounts. System webhooks listen to the whole Mixpost Enterprise instance. Use them to keep a CRM in sync, alert your team about a failed payment, or send lifecycle emails from your email platform:

  • a welcome email;
  • a reminder before a trial ends;
  • a nudge to connect a first account;
  • a note asking why a customer left.

Every event carries what such an email needs, such as who to write to, which plan they are on and the links to send them to. Your service never has to call Mixpost back.

Create a system webhook​

Open the Admin Console and click Webhooks under System. Then click Create webhook.

The form, the deliveries, the retries and the signature work exactly as they do for workspace webhooks. Only the list of events differs.

Payload​

Every request has the same envelope as a workspace webhook: the event name and its data.

{
"event": "workspace.trial_ending",
"data": {}
}

The headers are the same too: Content-Type, X-Request-Source and, when the webhook has a secret, X-Signature.

A few things hold for every event:

  • Dates come in two formats.
    • Fields that belong to a user, workspace, subscription or receipt are formatted for reading, for example "Oct 29, 2026".
    • Fields that belong to the event itself are ISO 8601 in UTC, for example "2026-10-29T10:00:00+00:00". Use these when you compare or schedule.
  • Workspaces are identified by their uuid. A workspace's owner is the user who pays for it and the one to write to.
  • Amounts are in the currency set under Billing. plan.currency repeats it where a plan appears.

Lifecycle fields​

The trial, onboarding and publishing events, and subscription.ended and subscription.downgraded_to_free, share a common set of fields about the workspace.

FieldDescription
workspaceThe workspace, with its owner, its subscriptions and, during a trial without a card, generic_subscription.
trial.card_on_filetrue for a trial started with a card at checkout, false for a trial without a card.
trial.ends_atWhen the trial ends, or null.
planThe plan the workspace is on or trying: id, name, monthly_amount, yearly_amount, currency.
usage.accounts_countHow many social accounts are connected.
usage.scheduled_posts_countHow many posts are scheduled.
urls.upgradeThe page where the owner chooses a plan.
urls.billingThe workspace's Subscription page.
urls.accountsThe page where social accounts are connected.

When events are sent​

  • Most events are sent the moment they happen.

  • Lifecycle events are found by a check that runs every hour:

    • workspace.trial_ending
    • workspace.trial_ended
    • workspace.no_accounts_connected
    • workspace.no_posts_scheduled
    • subscription.trial_converted
    • subscription.ended

    They need the scheduler running. Each is sent once per workspace and occurrence, however often the check runs.

  • Workspaces with unlimited access never receive the trial, billing and onboarding events. This includes the installer's workspace and any workspace an admin gives unlimited access to. workspace.post_failed is the exception.

Events​

EventSent when
user.createdA user signs up or is created.
user.email_verifiedA user verifies their email address.
user.deletedA user is deleted.
workspace.createdA workspace is created.
workspace.deletedA workspace is deleted.
workspace.trial_endingA trial ends in 3 days, and again in 1 day.
workspace.trial_endedA trial without a card ended without a subscription.
workspace.no_accounts_connectedA day after a workspace was created, it has no social account.
workspace.no_posts_scheduledA day after its first social account, a workspace has no post.
workspace.first_post_publishedA workspace publishes its first post.
workspace.post_failedA post fails to publish to an account.
subscription.createdThe payment platform reports a new subscription.
subscription.updatedThe payment platform reports a change to a subscription.
subscription.trial_convertedA trial turned into a paid subscription.
subscription.cancel_requestedThe owner cancels from the Subscription page.
subscription.canceledThe payment platform reports a cancellation.
subscription.endedA workspace loses access because its subscription ended or paused.
subscription.downgraded_to_freeA workspace moves to the free plan instead of losing access.
subscription.payment_succeededA payment goes through.
subscription.payment_failedA payment fails.

Users​

user.created​

A user signs up, signs in for the first time through single sign-on, or is created by an admin. from_admin is true when an admin created them in the console.

Example payload
{
"event": "user.created",
"data": {
"user": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": null,
"created_at": "Oct 15, 09:08am"
},
"from_admin": false
}
}

user.email_verified​

A user verifies their email address.

Example payload
{
"event": "user.email_verified",
"data": {
"user": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
}
}
}

user.deleted​

A user is deleted. What they were is taken before the deletion, so the payload is complete even though the user no longer exists.

FieldDescription
deleted_byuser when they deleted their own account, admin when an admin deleted them, unverified when the daily cleanup removed them for never verifying their email.
deleted_workspacesThe uuid of each workspace deleted together with the account. Only when the user deleted their own account; otherwise an empty list.
deleted_atWhen it happened.

When a user deletes their own account, each workspace they owned first sends workspace.deleted with deleted_by: account_deletion, then user.deleted follows. To write to the user once, react to user.deleted and skip workspace.deleted when deleted_by is account_deletion.

Example payload
{
"event": "user.deleted",
"data": {
"user": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"deleted_workspaces": ["9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13"],
"deleted_by": "user",
"deleted_at": "2026-10-22T10:00:00+00:00"
}
}

Workspaces​

workspace.created​

A workspace is created, at sign-up, by a user from their profile, or by an admin. from_admin is true when an admin created it in the console.

Example payload
{
"event": "workspace.created",
"data": {
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am"
},
"from_admin": false
}
}

workspace.deleted​

A workspace is deleted. Its subscription is cancelled at the same time.

FieldDescription
deleted_byowner from the workspace settings, admin from the console or the API, account_deletion when its owner deleted their account.
deleted_atWhen it happened.
Example payload
{
"event": "workspace.deleted",
"data": {
"workspace": {
"uuid": "6d1f3a9c-2e7b-4c58-a0d4-8b3e5f1c7a92",
"name": "Acme Labs",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 14, 08:00am",
"subscriptions": [],
"generic_subscription": {
"name": "Studio",
"free": false,
"trial_ends_at": "Oct 21, 2026",
"has_trial": true,
"has_expired_trial": true,
"remaining_trial_days": 0
}
},
"deleted_by": "owner",
"deleted_at": "2026-10-22T10:00:00+00:00"
}
}

Trials and onboarding​

workspace.trial_ending​

A trial ends in 3 days, and again when it ends in 1 day. days_left is 3 or 1. It is sent for both kinds of trial:

  • With a card on file (trial.card_on_file: true), the subscription starts and the card is charged when the trial ends.
  • Without a card, the owner has to choose a plan before then.

If a trial is extended, its reminders are sent again for the new end date.

Example payload
{
"event": "workspace.trial_ending",
"data": {
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am",
"subscriptions": [
{
"name": "default",
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": null,
"status": "trialing",
"recurring": false,
"trial_ends_at": "Oct 29, 2026",
"paused_from": null,
"ends_at": null
}
],
"generic_subscription": null
},
"trial": {
"card_on_file": true,
"ends_at": "2026-10-29T10:00:00+00:00"
},
"plan": {
"id": 1,
"name": "Studio",
"monthly_amount": 29,
"yearly_amount": 290,
"currency": "USD"
},
"usage": {
"accounts_count": 0,
"scheduled_posts_count": 0
},
"urls": {
"upgrade": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/upgrade",
"billing": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/billing",
"accounts": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/accounts"
},
"days_left": 3
}
}

workspace.trial_ended​

A trial without a card ended and the owner did not subscribe. The workspace is locked until they choose a plan.

When the instance has an active free plan, the workspace moves to it instead and sends subscription.downgraded_to_free with from_trial: true. In that case workspace.trial_ended is not sent.

A trial with a card does not end this way. When it ends, the card is charged, which sends subscription.trial_converted, or the payment fails, which sends subscription.payment_failed.

Example payload
{
"event": "workspace.trial_ended",
"data": {
"workspace": {
"uuid": "6d1f3a9c-2e7b-4c58-a0d4-8b3e5f1c7a92",
"name": "Acme Labs",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 14, 08:00am",
"subscriptions": [],
"generic_subscription": {
"name": "Studio",
"free": false,
"trial_ends_at": "Oct 21, 2026",
"has_trial": true,
"has_expired_trial": true,
"remaining_trial_days": 0
}
},
"trial": {
"card_on_file": false,
"ends_at": "2026-10-21T10:00:00+00:00"
},
"plan": {
"id": 1,
"name": "Studio",
"monthly_amount": 29,
"yearly_amount": 290,
"currency": "USD"
},
"usage": {
"accounts_count": 0,
"scheduled_posts_count": 0
},
"urls": {
"upgrade": "https://mixpost.example.com/6d1f3a9c-2e7b-4c58-a0d4-8b3e5f1c7a92/upgrade",
"billing": "https://mixpost.example.com/6d1f3a9c-2e7b-4c58-a0d4-8b3e5f1c7a92/billing",
"accounts": "https://mixpost.example.com/6d1f3a9c-2e7b-4c58-a0d4-8b3e5f1c7a92/accounts"
}
}
}

workspace.no_accounts_connected​

A day after the workspace was created, it still has no social account connected.

Example payload
{
"event": "workspace.no_accounts_connected",
"data": {
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am",
"subscriptions": [
{
"name": "default",
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": null,
"status": "trialing",
"recurring": false,
"trial_ends_at": "Oct 29, 2026",
"paused_from": null,
"ends_at": null
}
],
"generic_subscription": null
},
"trial": {
"card_on_file": true,
"ends_at": "2026-10-29T10:00:00+00:00"
},
"plan": {
"id": 1,
"name": "Studio",
"monthly_amount": 29,
"yearly_amount": 290,
"currency": "USD"
},
"usage": {
"accounts_count": 0,
"scheduled_posts_count": 0
},
"urls": {
"upgrade": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/upgrade",
"billing": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/billing",
"accounts": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/accounts"
}
}
}

workspace.no_posts_scheduled​

A day after its first social account was connected, the workspace has nothing scheduled, published or attempted. Drafts do not count. first_account_connected_at is when that first account was connected.

Example payload
{
"event": "workspace.no_posts_scheduled",
"data": {
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am",
"subscriptions": [
{
"name": "default",
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": null,
"status": "trialing",
"recurring": false,
"trial_ends_at": "Oct 29, 2026",
"paused_from": null,
"ends_at": null
}
],
"generic_subscription": null
},
"trial": {
"card_on_file": true,
"ends_at": "2026-10-29T10:00:00+00:00"
},
"plan": {
"id": 1,
"name": "Studio",
"monthly_amount": 29,
"yearly_amount": 290,
"currency": "USD"
},
"usage": {
"accounts_count": 1,
"scheduled_posts_count": 0
},
"urls": {
"upgrade": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/upgrade",
"billing": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/billing",
"accounts": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/accounts"
},
"first_account_connected_at": "2026-10-20T11:30:00+00:00"
}
}

workspace.first_post_published​

A workspace publishes its first post. A post that goes out to several accounts sends this once, for the first account it reaches. post.url opens the post in Mixpost, and account is the social account it went out to.

Example payload
{
"event": "workspace.first_post_published",
"data": {
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am",
"subscriptions": [
{
"name": "default",
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": null,
"status": "trialing",
"recurring": false,
"trial_ends_at": "Oct 29, 2026",
"paused_from": null,
"ends_at": null
}
],
"generic_subscription": null
},
"trial": {
"card_on_file": true,
"ends_at": "2026-10-29T10:00:00+00:00"
},
"plan": {
"id": 1,
"name": "Studio",
"monthly_amount": 29,
"yearly_amount": 290,
"currency": "USD"
},
"usage": {
"accounts_count": 1,
"scheduled_posts_count": 0
},
"urls": {
"upgrade": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/upgrade",
"billing": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/billing",
"accounts": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/accounts"
},
"post": {
"uuid": "5c0e8a7d-3b19-4f62-9d84-7a1e2c6b0f53",
"url": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/posts/5c0e8a7d-3b19-4f62-9d84-7a1e2c6b0f53"
},
"account": {
"id": 1,
"name": "Acme Studio",
"provider": "mastodon"
}
}
}

workspace.post_failed​

A post fails to publish to an account. A post going out to several accounts sends one event for each account it fails on. Workspaces with unlimited access receive it too.

FieldDescription
post.urlOpens the post in Mixpost.
accountThe social account it failed on.
errorThe reason the social network gave, when there is one.
is_first_failuretrue when the workspace has never published a post, so this is how its first attempt went.
failures_last_24hHow many posts failed in the workspace in the last 24 hours, this one included.
Example payload
{
"event": "workspace.post_failed",
"data": {
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am",
"subscriptions": [
{
"name": "default",
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": null,
"status": "trialing",
"recurring": false,
"trial_ends_at": "Oct 29, 2026",
"paused_from": null,
"ends_at": null
}
],
"generic_subscription": null
},
"trial": {
"card_on_file": true,
"ends_at": "2026-10-29T10:00:00+00:00"
},
"plan": {
"id": 1,
"name": "Studio",
"monthly_amount": 29,
"yearly_amount": 290,
"currency": "USD"
},
"usage": {
"accounts_count": 1,
"scheduled_posts_count": 0
},
"urls": {
"upgrade": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/upgrade",
"billing": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/billing",
"accounts": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/accounts"
},
"post": {
"uuid": "5c0e8a7d-3b19-4f62-9d84-7a1e2c6b0f53",
"url": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/posts/5c0e8a7d-3b19-4f62-9d84-7a1e2c6b0f53"
},
"account": {
"id": 1,
"name": "Acme Studio",
"provider": "mastodon"
},
"error": "The access token has expired.",
"is_first_failure": true,
"failures_last_24h": 1
}
}

Subscriptions​

subscription.created​

The payment platform reports a new subscription, usually right after checkout. A subscription that starts with a card trial arrives with status: trialing.

status is one of active, trialing, past_due, paused or canceled. plan.cycle is monthly or yearly.

Example payload
{
"event": "subscription.created",
"data": {
"name": "default",
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am"
},
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": {
"id": 1,
"name": "Studio",
"amount": 29,
"cycle": "monthly"
},
"status": "trialing",
"recurring": false,
"trial_ends_at": "Oct 29, 2026",
"paused_from": null,
"ends_at": null
}
}

subscription.updated​

The payment platform reports a change to a subscription: a new plan or cycle, a status change, a pause or a resume. The payload is the subscription as it is now, in the same shape as subscription.created.

Example payload
{
"event": "subscription.updated",
"data": {
"name": "default",
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am"
},
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": {
"id": 1,
"name": "Studio",
"amount": 29,
"cycle": "monthly"
},
"status": "trialing",
"recurring": false,
"trial_ends_at": "Oct 29, 2026",
"paused_from": null,
"ends_at": null
}
}

subscription.trial_converted​

A trial turned into a paid subscription:

  • A card trial was charged at its end: card_on_file_during_trial: true.
  • A workspace on a trial without a card subscribed: card_on_file_during_trial: false.
Example payload
{
"event": "subscription.trial_converted",
"data": {
"subscription": {
"name": "default",
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am"
},
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": {
"id": 1,
"name": "Studio",
"amount": 29,
"cycle": "monthly"
},
"status": "active",
"recurring": true,
"trial_ends_at": "Oct 22, 2026",
"paused_from": null,
"ends_at": null
},
"card_on_file_during_trial": true
}
}

subscription.cancel_requested​

The owner cancels from the workspace's Subscription page. The subscription keeps running until ends_at, the end of the period already paid for.

FieldDescription
reasonWhat the owner picked: too_expensive, missing_features, not_using, switched_service, technical_issues, temporary or other.
commentWhat they wrote, or null.
ends_atWhen the subscription ends.
billing_urlThe workspace's Subscription page, where the owner can resume before it ends.
Example payload
{
"event": "subscription.cancel_requested",
"data": {
"subscription": {
"name": "default",
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am"
},
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": {
"id": 1,
"name": "Studio",
"amount": 29,
"cycle": "monthly"
},
"status": "active",
"recurring": false,
"trial_ends_at": "Oct 22, 2026",
"paused_from": null,
"ends_at": "Nov 22, 2026"
},
"reason": "too_expensive",
"comment": "Too much for a team of two.",
"ends_at": "2026-11-22T09:58:00+00:00",
"billing_url": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/billing"
}
}

subscription.canceled​

The payment platform reports that a subscription was cancelled. That can be the owner cancelling from Mixpost or from the platform's portal, or the platform cancelling it after failed payments. The payload is the subscription, in the same shape as subscription.created.

Example payload
{
"event": "subscription.canceled",
"data": {
"name": "default",
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am"
},
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": {
"id": 1,
"name": "Studio",
"amount": 29,
"cycle": "monthly"
},
"status": "canceled",
"recurring": false,
"trial_ends_at": "Oct 22, 2026",
"paused_from": null,
"ends_at": "Nov 22, 2026"
}
}

subscription.ended​

A workspace actually loses access:

  • a cancelled subscription reached its end date (reason: canceled);
  • a pause took effect (reason: paused).

It is not sent when the workspace resumed, subscribed again or moved to the free plan.

FieldDescription
reasoncanceled or paused.
ended_atWhen access ended.
was_trialtrue when a card trial was cancelled before its first payment.
cancellationThe reason and comment the owner gave when cancelling, or null when they gave none or it paused.
Example payload
{
"event": "subscription.ended",
"data": {
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am",
"subscriptions": [
{
"name": "default",
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": null,
"status": "canceled",
"recurring": false,
"trial_ends_at": "Oct 22, 2026",
"paused_from": null,
"ends_at": "Nov 22, 2026"
}
],
"generic_subscription": null
},
"trial": {
"card_on_file": true,
"ends_at": "2026-10-22T09:58:00+00:00"
},
"plan": {
"id": 1,
"name": "Studio",
"monthly_amount": 29,
"yearly_amount": 290,
"currency": "USD"
},
"usage": {
"accounts_count": 1,
"scheduled_posts_count": 0
},
"urls": {
"upgrade": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/upgrade",
"billing": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/billing",
"accounts": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/accounts"
},
"subscription": {
"name": "default",
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am",
"subscriptions": [
{
"name": "default",
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": null,
"status": "canceled",
"recurring": false,
"trial_ends_at": "Oct 22, 2026",
"paused_from": null,
"ends_at": "Nov 22, 2026"
}
],
"generic_subscription": null
},
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": {
"id": 1,
"name": "Studio",
"amount": 29,
"cycle": "monthly"
},
"status": "canceled",
"recurring": false,
"trial_ends_at": "Oct 22, 2026",
"paused_from": null,
"ends_at": "Nov 22, 2026"
},
"reason": "canceled",
"ended_at": "2026-11-22T09:58:00+00:00",
"was_trial": false,
"cancellation": {
"reason": "too_expensive",
"comment": "Too much for a team of two."
}
}
}

subscription.downgraded_to_free​

A workspace moves to the free plan instead of losing access. This happens when a paid subscription ends, or a trial without a card expires, and the instance has an active free plan. It is sent instead of subscription.ended or workspace.trial_ended.

FieldDescription
previous_planThe name of the plan the workspace was on.
ended_atWhen that plan ended.
from_trialtrue when it was a trial without a card that expired.

plan in the lifecycle fields is now the free plan.

Example payload
{
"event": "subscription.downgraded_to_free",
"data": {
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am",
"subscriptions": [
{
"name": "default",
"platform_subscription_id": "sub_01jabc2def3ghi",
"platform_plan_id": "pri_01studio_monthly",
"plan": null,
"status": "canceled",
"recurring": false,
"trial_ends_at": "Oct 22, 2026",
"paused_from": null,
"ends_at": "Nov 22, 2026"
}
],
"generic_subscription": {
"name": "Free",
"free": true,
"trial_ends_at": null,
"has_trial": false,
"has_expired_trial": false,
"remaining_trial_days": 0
}
},
"trial": {
"card_on_file": true,
"ends_at": "2026-10-22T09:58:00+00:00"
},
"plan": {
"id": 1,
"name": "Studio",
"monthly_amount": 29,
"yearly_amount": 290,
"currency": "USD"
},
"usage": {
"accounts_count": 1,
"scheduled_posts_count": 0
},
"urls": {
"upgrade": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/upgrade",
"billing": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/billing",
"accounts": "https://mixpost.example.com/9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13/accounts"
},
"previous_plan": "Studio",
"ended_at": "2026-11-22T09:58:00+00:00",
"from_trial": false
}
}

subscription.payment_succeeded​

A payment goes through, a renewal included. The payload is the receipt.

Example payload
{
"event": "subscription.payment_succeeded",
"data": {
"uuid": "4e8a1c2b-7d3f-4a9e-8b5c-1f6d2e9a0b37",
"workspace": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am"
},
"transaction_id": "txn_01jxyz9klm8nop",
"invoice_number": "1234-56789",
"amount": "29",
"tax": "0",
"currency": "USD",
"receipt_url": null,
"description": "Studio - Monthly",
"created_at": "Oct 22, 2026",
"paid_at": "Oct 22, 2026",
"paid_at_raw": "2026-10-22 09:58"
}
}

subscription.payment_failed​

A payment fails. The payment platform usually retries before it cancels the subscription. The payload is the workspace itself, with its owner.

Example payload
{
"event": "subscription.payment_failed",
"data": {
"uuid": "9b2c7e41-5f3a-4d8e-b1c6-2a7f9e0d4c13",
"name": "Acme Studio",
"avatar": null,
"owner_id": 1,
"owner": {
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"avatar": null,
"is_admin": false,
"settings": [],
"email_verified_at": "Oct 15, 09:12am",
"created_at": "Oct 15, 09:08am"
},
"access_status": "subscription",
"created_at": "Oct 15, 09:10am"
}
}