Billing API
Plans, prices, checkout links and the subscription. 10 ops: get_pricing, get_account, get_billing, create_checkout_link, subscribe, cancel_subscription, resume_subscription, claim_checkout, create_billing_portal_link, get_billing_link.
Plans, prices, checkout links and the subscription.
Get pricing · POST /api/v1/get_pricing · scope billing:read or GET …?input=
The plans (Free, Plus): price {monthly, yearly} in USD, photo/text analyses on our model included per day (logging a meal you analyzed yourself, barcode scans and edits are free and unlimited), limits (members, history days; null is unlimited), features, a checkout_url per paid plan, and how_to_buy. The same document as GET /api/v1/pricing; needs no credential (REST, the catalog MCP server at /api/mcp/catalog, `gutlog pricing`). Call before recommending or buying a plan.
curl -X POST https://getgutlog.com/api/v1/get_pricing \ -H "Authorization: Bearer gutlog_…"npx @meterapp/gutlog get_pricing{
"type": "object",
"properties": {}
}get_account
readGet account · POST /api/v1/get_account · scope billing:read or GET …?input=
Who this credential acts for and what it may use: the organization, your role in it (viewer, member, admin, owner) and whether you are a person, an OAuth client or an API key (acting_as, with the key's scopes), the plan in force (status, interval, renewal or end date), today's usage against the daily allowance (analyses) with what remains and when it resets, and next_tier: what the next plan adds, its price and a checkout_url. Same data as GET /api/v1/account and `gutlog account`. Call when a human asks about their plan or an analysis was refused for the daily limit.
curl -X POST https://getgutlog.com/api/v1/get_account \ -H "Authorization: Bearer gutlog_…"npx @meterapp/gutlog get_account{
"type": "object",
"properties": {}
}get_billing
readGet billing · POST /api/v1/get_billing · scope billing:read or GET …?input=
This organization's plan, subscription status, renewal or end date, whether a card is saved (so subscribe can charge it), and today's usage against the plan (analyses, members). Pass refresh: true right after a human finished a checkout to pull the latest state from Stripe.
curl -X POST https://getgutlog.com/api/v1/get_billing \ -H "Authorization: Bearer gutlog_…"npx @meterapp/gutlog get_billing{
"type": "object",
"properties": {
"refresh": {
"default": false,
"description": "Re-read the subscription from Stripe instead of the stored copy.",
"type": "boolean"
}
}
}Create checkout link · POST /api/v1/create_checkout_link · scope billing:write
A Stripe Checkout URL where a human pays for a plan; hand it to them (or open it in their browser). Works before signup: with no credential (REST, the catalog MCP server, `gutlog upgrade` before login) the human pays first, then signs in with the same email and the plan attaches to their organization. Nothing is charged and the plan does not change until they complete it; then get_billing {refresh: true} shows the new plan. The link expires after 24 hours. If the organization already has a subscription, the URL is a Stripe page where they confirm the plan change instead. Returns {url, kind: checkout | plan_change, plan, interval, amount_cents, expires_at, session_id}. Never collect card details yourself.
curl -X POST https://getgutlog.com/api/v1/create_checkout_link \ -H "Authorization: Bearer gutlog_…" \ -H "Content-Type: application/json" \ -d '{"plan":"plus"}'npx @meterapp/gutlog create_checkout_link --json '{"plan":"plus"}'{
"type": "object",
"properties": {
"plan": {
"type": "string",
"enum": [
"plus"
],
"description": "plus. get_pricing lists what it includes."
},
"interval": {
"default": "month",
"description": "month ($8), or year ($60).",
"type": "string",
"enum": [
"month",
"year"
]
},
"ref": {
"description": "Optional attribution slug for the link (e.g. agent-cursor). Defaults to the surface: agent-mcp, agent-cli or agent-api.",
"type": "string",
"pattern": "^[a-z0-9][a-z0-9_-]{0,39}$"
}
},
"required": [
"plan"
]
}Subscribe · POST /api/v1/subscribe · scope billing:write
Start or change this organization's paid plan in one call, charging the card already saved for the organization. Only after a human approved this plan and price: confirm must be true. Without a saved card (or if the card needs the human, e.g. 3-D Secure) nothing is charged and it returns status checkout_required with a checkout_url for a human to finish. A plan change is prorated and invoiced immediately. Returns {status: subscribed | changed | unchanged | checkout_required, billing}.
curl -X POST https://getgutlog.com/api/v1/subscribe \ -H "Authorization: Bearer gutlog_…" \ -H "Content-Type: application/json" \ -d '{"plan":"plus","confirm":false}'npx @meterapp/gutlog subscribe --json '{"plan":"plus","confirm":false}'{
"type": "object",
"properties": {
"plan": {
"type": "string",
"enum": [
"plus"
],
"description": "plus. get_pricing lists what it includes."
},
"interval": {
"default": "month",
"description": "month ($8), or year ($60).",
"type": "string",
"enum": [
"month",
"year"
]
},
"confirm": {
"type": "boolean",
"const": true,
"description": "Must be true: a human has seen the plan and price and asked you to buy it. Never set it on your own initiative."
}
},
"required": [
"plan",
"confirm"
]
}Cancel subscription · POST /api/v1/cancel_subscription · scope billing:write
Cancel the paid plan at the end of the current period (no refund; the plan stays until then, then the organization is on Free). Only when a human asked: confirm must be true. Every cancellation records why: ask the human for the reason (or prefer_not_to_say) and any comment in their words. resume_subscription undoes it before the period ends.
curl -X POST https://getgutlog.com/api/v1/cancel_subscription \ -H "Authorization: Bearer gutlog_…" \ -H "Content-Type: application/json" \ -d '{"confirm":false,"reason":"too_expensive"}'npx @meterapp/gutlog cancel_subscription --json '{"confirm":false,"reason":"too_expensive"}'{
"type": "object",
"properties": {
"confirm": {
"type": "boolean",
"const": true,
"description": "Must be true: a human has seen the plan and price and asked you to buy it. Never set it on your own initiative."
},
"reason": {
"type": "string",
"enum": [
"too_expensive",
"not_using",
"missing_feature",
"accuracy",
"logging_effort",
"switched",
"privacy",
"temporary",
"other",
"prefer_not_to_say"
],
"description": "Why they are cancelling: too_expensive (Too expensive), not_using (Not using it enough), missing_feature (Missing a feature I need), accuracy (Nutrition or ingredients were not accurate enough), logging_effort (Logging took too much effort), switched (Switched to another app), privacy (Privacy concerns), temporary (Only needed it for a while), other (Something else), prefer_not_to_say (Prefer not to say)."
},
"comment": {
"description": "Anything else they said about why, in their words.",
"type": "string",
"maxLength": 2000
}
},
"required": [
"confirm",
"reason"
]
}Resume subscription · POST /api/v1/resume_subscription · scope billing:write
Undo a cancellation that has not taken effect yet, so the plan renews as before. Nothing is charged until the normal renewal date.
curl -X POST https://getgutlog.com/api/v1/resume_subscription \ -H "Authorization: Bearer gutlog_…"npx @meterapp/gutlog resume_subscription{
"type": "object",
"properties": {}
}Claim checkout · POST /api/v1/claim_checkout · scope billing:write
Attach a checkout paid before signup (create_checkout_link without a credential) to this organization, by its session_id (cs_…). Usually automatic: returning from Stripe, or signing up with the email used at checkout, claims it. Call it when a human paid first and the plan has not appeared. Returns {outcome: claimed | already_yours, billing}.
curl -X POST https://getgutlog.com/api/v1/claim_checkout \ -H "Authorization: Bearer gutlog_…" \ -H "Content-Type: application/json" \ -d '{"session_id":"session_id"}'npx @meterapp/gutlog claim_checkout --json '{"session_id":"session_id"}'{
"type": "object",
"properties": {
"session_id": {
"type": "string",
"pattern": "^cs_(live|test)_[A-Za-z0-9]+$",
"description": "The Checkout Session id create_checkout_link returned (cs_live_… or cs_test_…)."
}
},
"required": [
"session_id"
]
}Create billing portal link · POST /api/v1/create_billing_portal_link · scope billing:write
A private Stripe page where a human downloads invoices, updates the card or billing details, or cancels. The link is for a human and expires after a few minutes of inactivity; never open it on your own.
curl -X POST https://getgutlog.com/api/v1/create_billing_portal_link \ -H "Authorization: Bearer gutlog_…"npx @meterapp/gutlog create_billing_portal_link{
"type": "object",
"properties": {}
}Get billing link · POST /api/v1/get_billing_link · scope billing:write
The Stripe customer portal for a human: invoices, card and billing details, plan change and cancellation. The same as create_billing_portal_link, under the name every Meter product uses (POST /api/v1/billing/portal, `gutlog billing portal`). The link expires after a few minutes of inactivity; never open it on your own.
curl -X POST https://getgutlog.com/api/v1/get_billing_link \ -H "Authorization: Bearer gutlog_…"npx @meterapp/gutlog get_billing_link{
"type": "object",
"properties": {}
}