Billing
A free trial, then a prepaid balance. New workspaces publish for free for 7 days from their first published post (14 days at most from signing up); X and phone numbers need balance. After the first top-up, connected accounts are charged day by day and usage (X API, messages, phone numbers, calls, SMS) as it happens. Topping it up happens in the dashboard.
Get the balance
Section titled “Get the balance”/v1/billingBalance, the free trial, connected accounts and what they cost. Once the trial ends without a top-up, or the balance is used up after paying, connecting accounts and publishing or sending answer 402; scheduled posts of an ended trial wait as paused until the first top-up.
Response 200
data
enabledbooleanrequiredFalse while billing is not available: nothing is charged or limited.
balancenumberrequiredPrepaid balance in euro cents (up to three decimals):
1250.5is 12.505 €. Negative when charges outran it.currencystringrequiredconnectedAccountsintegerrequiredtrialobjectThe free trial: connect any network (X and phone numbers need balance) and publish without paying. When it ends unpaid, scheduled posts pause until the first top-up.
trial
statusstringrequiredpending: nothing published yet;active: the free days run;expired: ended without paying;converted: paid.registeredAtstring (date-time)requiredstartedAtstring (date-time)First published post: the free days count from here.
endsAtstring (date-time)required7 days after the first published post, and never more than 14 days after signing up.
daysLeftinteger | nullrequiredWhole days left (0 on the last day); null once it ended or was paid.
trialDaysintegerrequiredFree days once it starts: 7, fewer when the 14-day limit cuts it.
maxAccountsintegerrequiredAccounts the trial covers (20). Connecting a 21st needs balance, and the first top-up ends the trial.
bannerstringWhat the dashboard shows now about the trial.
statsobjectrequiredstats
publishedintegerrequiredscheduledintegerrequiredpausedintegerrequiredScheduled posts on hold since the trial ended.
accountsintegerrequired
monthlyEstimateintegerrequiredMonthly price of the accounts connected now, in cents. It is charged day by day.
dailyEstimatenumberrequiredWhat those accounts cost today, in cents (up to three decimals).
daysLeftinteger | nullrequiredWhole days the balance covers at that cost; null when nothing is charged daily.
linesobject[]requiredlines
fromintegerrequiredtointeger | nullrequiredaccountsintegerrequiredunitAmountintegerrequiredCents per account and month.
amountintegerrequired
canConnectMorebooleanrequiredWhether one more account can be connected right now.
blockedbooleanrequiredPublishing is on hold: the free trial ended without a top-up, or the balance is used up. Nothing is deleted.
cardobjectThe saved payment method, for automatic recharges.
card
brandstringrequiredCard brand (
visa,mastercard…) or another saved method (link,sepa_debit).last4stringexpMonthintegerexpYearinteger
autoRechargeobjectautoRecharge
enabledbooleanrequiredthresholdintegerrequiredRecharge when the balance falls below this, in cents.
amountintegerrequiredWhat each recharge adds, in cents.
monthlyLimitintegerrequiredMost that automatic recharges add in a calendar month, in cents.
autoRechargeErrorobjectWhy the last automatic recharge failed; it switched itself off.
autoRechargeError
atstring (date-time)requiredmessagestringrequired
autoRechargedThisMonthintegerrequiredAdded by automatic recharges this calendar month, in cents.
topUpobjectrequiredAllowed top-up amounts, in cents.
topUp
minintegerrequiredmaxintegerrequired
hasPortalbooleanrequiredWhether the billing portal (invoices, payment method) is available.
curl "https://api.marsial.dev/v1/billing" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/billing', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/billing", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]List balance movements
Section titled “List balance movements”/v1/billing/movementsTop-ups and charges, newest first.
Parameters
limitinteger
Response 200
data []
idstringrequiredkindstringrequiredamountnumberrequiredEuro cents, up to three decimals: positive adds, negative debits.
-9.678is 0.09678 €.currency"eur"requiredThe currency of
amount(in cents).atstring (date-time)requireddaystringUTC day (YYYY-MM-DD) a charge covers.
accountsintegerAccounts a day was charged for.
familystringUsage family of a usage charge: X API, messages, phone numbers, calls, SMS or SMS registration.
curl "https://api.marsial.dev/v1/billing/movements" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/billing/movements', { headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.get( "https://api.marsial.dev/v1/billing/movements", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Top up the balance
Section titled “Top up the balance”/v1/billing/top-upDashboard onlyOpens a payment page. The balance grows once the payment succeeds; the card is saved for automatic recharges.
Body
amountintegerrequiredBalance to add, in cents (taxes, if any, on top). Limits come with GET /v1/billing.
successUrlstring (uri)requiredDashboard page to come back to after paying.
cancelUrlstring (uri)requiredDashboard page to come back to if the user leaves Checkout.
Response 200
data
urlstring (uri)requiredSend the user here.
curl -X POST "https://api.marsial.dev/v1/billing/top-up" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/billing/top-up', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/billing/top-up", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Set automatic recharges
Section titled “Set automatic recharges”/v1/billing/auto-rechargeDashboard onlyTops up the saved card when the balance falls below the threshold, up to a monthly limit. Needs one top-up first.
Body
enabledbooleanrequiredthresholdintegerrequiredRecharge when the balance falls below this, in cents.
amountintegerrequiredWhat each recharge adds, in cents.
monthlyLimitintegerrequiredMost that automatic recharges may add in a calendar month, in cents.
Response 200
data
enabledbooleanrequiredFalse while billing is not available: nothing is charged or limited.
balancenumberrequiredPrepaid balance in euro cents (up to three decimals):
1250.5is 12.505 €. Negative when charges outran it.currencystringrequiredconnectedAccountsintegerrequiredtrialobjectThe free trial: connect any network (X and phone numbers need balance) and publish without paying. When it ends unpaid, scheduled posts pause until the first top-up.
trial
statusstringrequiredpending: nothing published yet;active: the free days run;expired: ended without paying;converted: paid.registeredAtstring (date-time)requiredstartedAtstring (date-time)First published post: the free days count from here.
endsAtstring (date-time)required7 days after the first published post, and never more than 14 days after signing up.
daysLeftinteger | nullrequiredWhole days left (0 on the last day); null once it ended or was paid.
trialDaysintegerrequiredFree days once it starts: 7, fewer when the 14-day limit cuts it.
maxAccountsintegerrequiredAccounts the trial covers (20). Connecting a 21st needs balance, and the first top-up ends the trial.
bannerstringWhat the dashboard shows now about the trial.
statsobjectrequiredstats
publishedintegerrequiredscheduledintegerrequiredpausedintegerrequiredScheduled posts on hold since the trial ended.
accountsintegerrequired
monthlyEstimateintegerrequiredMonthly price of the accounts connected now, in cents. It is charged day by day.
dailyEstimatenumberrequiredWhat those accounts cost today, in cents (up to three decimals).
daysLeftinteger | nullrequiredWhole days the balance covers at that cost; null when nothing is charged daily.
linesobject[]requiredlines
fromintegerrequiredtointeger | nullrequiredaccountsintegerrequiredunitAmountintegerrequiredCents per account and month.
amountintegerrequired
canConnectMorebooleanrequiredWhether one more account can be connected right now.
blockedbooleanrequiredPublishing is on hold: the free trial ended without a top-up, or the balance is used up. Nothing is deleted.
cardobjectThe saved payment method, for automatic recharges.
card
brandstringrequiredCard brand (
visa,mastercard…) or another saved method (link,sepa_debit).last4stringexpMonthintegerexpYearinteger
autoRechargeobjectautoRecharge
enabledbooleanrequiredthresholdintegerrequiredRecharge when the balance falls below this, in cents.
amountintegerrequiredWhat each recharge adds, in cents.
monthlyLimitintegerrequiredMost that automatic recharges add in a calendar month, in cents.
autoRechargeErrorobjectWhy the last automatic recharge failed; it switched itself off.
autoRechargeError
atstring (date-time)requiredmessagestringrequired
autoRechargedThisMonthintegerrequiredAdded by automatic recharges this calendar month, in cents.
topUpobjectrequiredAllowed top-up amounts, in cents.
topUp
minintegerrequiredmaxintegerrequired
hasPortalbooleanrequiredWhether the billing portal (invoices, payment method) is available.
curl -X PUT "https://api.marsial.dev/v1/billing/auto-recharge" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/billing/auto-recharge', { method: 'PUT', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.put( "https://api.marsial.dev/v1/billing/auto-recharge", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]Open the billing portal
Section titled “Open the billing portal”/v1/billing/portalDashboard onlyInvoices and the saved payment method.
Body
returnUrlstring (uri)requiredDashboard page to come back to.
Response 200
data
urlstring (uri)requiredSend the user here.
curl -X POST "https://api.marsial.dev/v1/billing/portal" \ -H "Authorization: Bearer $MARSIAL_API_KEY"const res = await fetch('https://api.marsial.dev/v1/billing/portal', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MARSIAL_API_KEY}`, },});const { data } = await res.json();import os, requests
res = requests.post( "https://api.marsial.dev/v1/billing/portal", headers={"Authorization": f"Bearer {os.environ['MARSIAL_API_KEY']}"},)data = res.json()["data"]© 2026 Marsial by TWOFACES ·marsial.dev ·Dashboard ·soporte@twofacesco.com