Cubbie API
Build integrations that feed Cubbie, extend Cubbie, and distribute Cubbie-powered partner surfaces without replacing the Cubbie dashboard.
Dashboard-first API strategy
Cubbie APIs are designed to make the Cubbie workspace more useful. Use the API to ingest stack data, automate partner and vendor operations, send signed events, and deep-link users back into Cubbie for comparison, redemption, renewal, and procurement workflows.
API Surfaces
Buyer stack ingestion
Send subscriptions, usage, seat, renewal, and spend signals into Cubbie so the Cubbie dashboard remains the source of truth.
Advisor + renewal outputs
Trigger analyses and read recommendation summaries for notifications, while deep-linking users back into Cubbie for decisions.
Partner-program distribution
Install Cubbie-powered hosted pages, widgets, and custom-domain surfaces without hiding that Cubbie powers the perks experience.
Vendor + partner webhooks
Subscribe systems to signed events such as redemptions, orders, payouts, referrals, and account updates.
Vendor-admin integrations
Read seats, active users, and plan tier from supported vendor admin APIs, with optional spend and identity signals from connections enabled for the workspace. Browse the current catalog at /integrations.
What We Intentionally Do Not Expose
Cubbie does not provide an unrestricted public API to clone the entire catalog, deals marketplace, rankings, or recommendation experience off-platform. Partner surfaces return Cubbie-hosted URLs, embeds, scripts, and attribution-safe JSON where appropriate, with Cubbie branding and links back to the workspace.
Current Launch Surface
The developer platform is intentionally split by use case: public v1 REST for stack ingestion and Cubbie workspace workflows, partner-program APIs for perks distribution, and vendor webhook tooling for event automation.
| Surface | Route | Status | What It Does |
|---|---|---|---|
| Public v1 REST | /api/v1/* | Available | API-key authenticated catalog search and product details, order proposals, buyer stack, advisor, renewal, vendor-admin, and partner-program endpoints, plus a vendor organization's own offers and orders. Cubbie Points endpoints use separate ck_ tokens. |
| OpenAPI contract | /api/v1/openapi.json | Available | Machine-readable OpenAPI 3.1 schema for public v1 REST plus the member v2 pricing ledger. |
| Member pricing ledger | /api/v2/products/:slug/pricing | Available | Structured list pricing for accounts with verified email and completed onboarding, with exact micros and a safe verified_at freshness timestamp; private evidence and review metadata are withheld. |
| Partner programs | /api/partner-programs/* | Available | Dashboard-created perks programs with hosted pages, embeds, custom domains, public JSON, referrals, and click tracking. Server-side callers should always use the URLs from `urls` on their own perks domain (for example perks.yourcompany.com). Requests to www.cubbie.com from servers may be challenged and fail. |
| Vendor webhooks | /api/vendor/webhooks/* | Dashboard authenticated | Self-serve vendor endpoint registration, signed deliveries, retries, delivery logs, and secret rotation. |
| OAuth 2.1 | /api/oauth/* | Available | Authorization-code flow with PKCE and dynamic client registration for MCP clients, discovered from /.well-known/oauth-authorization-server. Consent mints a scoped, revocable API key for one buyer organization. Client-credentials token issuance exists for approved confidential clients. |
Authentication
Public v1 catalog, commerce, stack, advisor, renewal, vendor-admin, partner-program, and vendor endpoints require a cb_live_... API key. An organization owner or admin creates one from the Buyer Dashboard under the "API Keys" section. Vendor offer and order endpoints take a vendor-organization key. Cubbie Points endpoints use separate ck_... credit tokens, and vendor webhooks are managed inside the authenticated vendor dashboard.
Getting an API Key
- Scroll to the "API Keys" section and click "Create New Key." Only an organization owner or admin can create, rescope, revoke, or rotate keys; other members can view them.
- Copy the key immediately -- it is shown only once.
Authenticating Requests
Pass the key in the Authorization header:
Authorization: Bearer cb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKeys follow the format cb_live_ followed by 32 hex characters. Keep your keys secret and never commit them to source control.
Scopes
API keys are scope-limited. Create the narrowest key possible for each integration. A new key starts with catalog:read and offers:read only; every scope that touches your organization's data is granted on purpose by an organization owner or admin, and a read scope never includes write access.
subscriptions:read returns vendors, products, spend, renewal dates and status. Owner names, owner emails and notes are returned only to keys that also hold subscriptions:contacts:read; otherwise those fields are omitted. Referral leads for partner programs need partner_programs:referrals:read. A key stops working as soon as the member who created it leaves the organization.
| Scope | Purpose |
|---|---|
| Catalog Public product, category and pricing data. Included on every new buyer-organization key. | |
catalog:read | Search the Cubbie software catalog and read product details, attributes, and categories. |
offers:read | Read publicly visible offers and pricing for catalog products. |
| Your stack and spend The organization's subscriptions, renewals, usage and connected vendor signals. | |
subscriptions:read | Read the organization's stack registry: vendors, products, spend, renewal dates and status. Owner contacts and notes are not included. |
subscriptions:contacts:read | Owner names, owner emails and notes on subscriptions. Grant only to systems that need to reach the people behind a renewal. |
subscriptions:write | Create, update, delete, or bulk import stack registry records. |
renewals:read | Read upcoming renewal windows for notifications and deep links. |
usage:write | Send utilization, seat, and activity signals into Cubbie. |
vendor_admin:read | Read vendor-admin connections, seat and usage signals, and rightsizing recommendations. |
| Advisor Recommendations and analyses for the organization's stack. | |
advisor:read | Read current Cubbie advisor recommendations. |
advisor:write | Trigger Cubbie advisor analyses. |
| Partner programs Perk programs, their surfaces and the leads they collect. | |
partner_programs:read | Read partner-program surfaces, URLs, install snippets, custom domains and content assets. |
partner_programs:referrals:read | Referral leads, including contact names and emails, for your partner programs. |
partner_programs:write | Create and update partner programs, attach custom domains, and publish content assets. |
| Vendor tools A vendor organization's own offers and the orders placed on them. | |
vendor:offers:read | Read the vendor organization's own offers and their status. |
vendor:orders:read | Read orders placed against the vendor organization's offers. |
| Agent authority What an agent may do with orders. Every order is still paid by a person. | |
commerce:propose | Propose orders that a human in the organization must approve before any payment occurs. Agents can never execute a charge. |
commerce:execute | Orders inside the key's per-order and monthly caps skip the human approval step. Payment is still completed by a person; agents never charge a card. |
| Webhooks Event delivery to your endpoints. Coming soon. | |
webhooks:read | Reserved for a future release -- webhook endpoints are currently managed from the vendor dashboard. |
webhooks:write | Reserved for a future release -- webhook endpoints are currently managed from the vendor dashboard. |
Base URLs
| Surface | Base |
|---|---|
| Public v1 REST | https://cubbie.com/api/v1 |
| Partner-program public surfaces | https://cubbie.com/api/partner-programs/public/:slug |
| Vendor webhook management | https://cubbie.com/api/vendor/webhooks |
| OAuth token issuance | https://cubbie.com/api/oauth/token |
All endpoints return JSON with the shape { "ok": true, "data": ... } on success or { "ok": false, "error": { "message": "..." } } on failure.
Partner Programs
Partner programs are the API-backed perks surfaces companies create from Cubbie to power pages like perks.example.com, dashboard embeds, and curated sponsorship panels. The Cubbie dashboard remains the setup workspace: partners create the program, select perks, configure branding, add allowed embed origins, and connect custom domains.
The public API exposes installable outputs for those programs: hosted page URLs, iframe URLs, script snippets, and attribution-safe JSON URLs. This gives partners distribution without turning Cubbie into an invisible white-label catalog.
| Endpoint | Purpose |
|---|---|
POST /api/v1/partner-programs | Create a Cubbie-powered perks, referral, or hybrid partner program. |
GET /api/v1/partner-programs/:id | Read one program's full configuration, surface URLs, and embed snippets. |
PATCH /api/v1/partner-programs/:id | Update branding, audience copy, access mode, embedded layout, and curated selection rules. |
GET /api/v1/partner-programs/:id/domains | List connected custom domains with verification state and DNS records. |
POST /api/v1/partner-programs/:id/domains | Attach a custom perks subdomain and return the DNS verification instructions. |
GET /api/v1/partner-programs/:id/assets | List the FAQs, announcements, benefits, and resources on the partner surface. |
POST /api/v1/partner-programs/:id/assets | Publish FAQs, announcements, benefits, and resources into the partner surface. |
GET /api/v1/partner-programs/:id/referrals | Read partner referral leads captured by hosted pages and embeds, including contact names and emails. Requires partner_programs:referrals:read. |
Worked request and response examples for the read endpoints are included in the Endpoints reference below.
Vendor Admin API
Vendor-admin endpoints expose what Cubbie pulls from the admin APIs of the vendors you connect from the dashboard: connection metadata, the latest seat, usage, and billing snapshot per vendor, and the rightsizing recommendations Cubbie computes from those signals. All three endpoints are read-only and require a cb_live_... API key with the vendor_admin:read scope. Credentials for connected vendors are never returned.
| Endpoint | Purpose |
|---|---|
GET /api/v1/vendor-admin/connections | List connected vendor-admin integrations with sync status. Metadata only. |
GET /api/v1/vendor-admin/signals | Latest seat, usage, and billing snapshot per vendor. Filter with vendor_slug; cap with limit. |
GET /api/v1/vendor-admin/recommendations | Rightsizing recommendations with action filtering applied (dismissed hidden, snoozed hidden until expiry, accepted flagged). |
Vendor Webhooks
Vendors can register webhook endpoints from the vendor dashboard to receive signed event deliveries. Cubbie signs each delivery with HMAC-SHA256 and sends X-Cubbie-Signature, X-Cubbie-Timestamp, and X-Cubbie-Event-Id headers.
Failed deliveries retry after 1 minute, 5 minutes, 30 minutes, 2 hours, and 12 hours. After repeated failures, endpoints are temporarily disabled to protect both systems.
Supported vendor events
deal.created
deal.redeemed
deal.expired
order.completed
order.refunded
subscription.cancelled
subscription.renewed
payout.released
payout.failed
review.received
vendor.account_updatedAI Agents and MCP
Cubbie is agent-native. Any MCP client (Claude, ChatGPT, Cursor, or a custom procurement agent) can connect to the Cubbie MCP server and search the catalog, compare products, browse outcomes, read the organization's stack and spend, pull decision evidence, and propose purchases.
https://cubbie.com/api/mcpAnonymous connections get the public catalog tools (search_catalog, get_product_details, compare_products, list_outcomes, get_outcome). Passing an API key as Authorization: Bearer cb_live_... unlocks the org-scoped tools (get_my_stack, get_my_spend, add_to_stack, get_product_intelligence, propose_order), gated by the same scopes as the REST API.
Purchases are propose-only by default
An agent never charges a card on Cubbie. propose_order (and POST /api/v1/commerce/orders) computes the price server-side from the offer and creates a pending order. By default the order goes to the organization's approvals inbox with status proposed; a person approves it and then completes payment.
A key granted commerce:execute, with a per-order cap and a monthly cap set in the dashboard key manager, skips the approval step for orders inside those caps: the order comes back with status auto_approved_awaiting_payment and a checkoutUrl where a person completes payment. Orders over a cap are refused. Caps are enforced when the agent proposes and re-checked when a person approves. Neither commerce:propose nor commerce:execute is granted by default.
Machine discovery: https://cubbie.com/llms.txt summarizes all agent-facing interfaces and the rules agents are asked to follow.
Agent Recipes
Recipes for building a procurement agent on the Cubbie MCP server or the REST API. Every order an agent files follows the purchase paths above.
Recipe: renewal watchdog
Poll GET /api/v1/renewals/upcoming (scope renewals:read), research alternatives with search_catalog, get_product_details, and get_product_intelligence, then propose a replacement or a renegotiation with propose_order before the renewal date. Every proposal lands in the approvals inbox.
renewals = GET /api/v1/renewals/upcoming?days=45
for renewal in renewals:
candidates = search_catalog(renewal.category)
evidence = get_product_intelligence(top_candidate)
propose_order(offer, note="replace or renegotiate " + renewal.product)
# every proposal -> approvals inboxRecipe: stack gap filler
Read the organization's stack with get_my_stack, use get_product_intelligence to find category gaps, shortlist candidates with compare_products, and file a propose_order with a note explaining the gap for the human approver.
Connect with OAuth
MCP clients can also connect via OAuth 2.1 (dynamic client registration + PKCE). The client discovers everything from /.well-known/oauth-authorization-server. The consent screen grants scoped access to one buyer organization and mints a revocable API key. commerce:execute can never be granted via OAuth. Spending caps must be configured in the dashboard key manager.
OpenAPI
Use the OpenAPI schema to generate typed clients, validate requests in tests, or import the API into tools like Postman and Scalar.
https://cubbie.com/api/v1/openapi.jsonPrefer a ready-to-import collection? Use https://cubbie.com/api/v1/postman.json.
API Explorer
Test public v1 calls from your browser. Keys stay in this page state and are not stored.
Endpoints
Health check. No authentication required.
curl https://cubbie.com/api/v1/health{
"ok": true,
"data": {
"status": "ok",
"version": "1.0.0",
"timestamp": "2026-03-29T12:00:00.000Z"
}
}OpenAPI 3.1 contract for public v1 APIs and the v2 pricing ledger. No authentication required.
curl https://cubbie.com/api/v1/openapi.json{
"openapi": "3.1.0",
"info": {
"title": "Cubbie Public API",
"version": "1.0.0"
}
}Published structured USD pricing for one product. Requires a current account session, verified email, and completed onboarding. Amounts are USD micros encoded as strings; verified_at is the only schedule freshness signal. Evidence, source excerpts, confidence, reviewer identity, and internal notes are not returned.
curl -H "Authorization: Bearer $CUBBIE_SESSION_TOKEN" https://cubbie.com/api/v2/products/remote/pricing{
"ok": true,
"data": {
"schema_version": 2,
"display_currency": "USD",
"product": { "slug": "remote", "name": "Remote" },
"offerings": [{
"offering_key": "payroll",
"name": "Global Payroll",
"offering_kind": "service",
"schedules": [{
"version": 3,
"currency": "USD",
"region_code": "GLOBAL",
"audience_key": "all_buyers",
"sales_channel": "direct",
"verified_at": "2026-08-20T14:30:00.000Z",
"plans": [{
"plan_key": "managed-payroll",
"name": "Managed Payroll",
"components": [{
"component_key": "employee-month",
"amount_micros": "50000000",
"currency": "USD",
"charge_unit": "employee",
"price_period": { "count": 1, "unit": "month" }
}]
}]
}]
}]
}
}List all subscriptions for your organization, sorted by most recently updated. Requires subscriptions:read. owner_name, owner_email and notes appear only when the key also holds subscriptions:contacts:read; the example shows the default shape without them.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/subscriptions{
"ok": true,
"data": {
"items": [
{
"id": "uuid",
"vendor_name": "Slack",
"product_name": "Slack Business+",
"source": "integration",
"annualized_spend_cents": 1440000,
"renewal_date": "2027-01-15",
"status": "active",
"created_at": "2026-03-29T12:00:00.000Z",
"updated_at": "2026-04-02T09:15:00.000Z"
}
]
}
}Add a subscription to your stack registry. Requires subscriptions:write. The response echoes owner_name, owner_email and notes only when the key also holds subscriptions:contacts:read.
curl -X POST \
-H "Authorization: Bearer cb_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"vendor_name":"Slack","product_name":"Slack Business+","annualized_spend_cents":1440000,"renewal_date":"2027-01-15"}' \
https://cubbie.com/api/v1/subscriptions{
"ok": true,
"data": {
"id": "uuid",
"vendor_name": "Slack",
"product_name": "Slack Business+",
"source": "integration",
"annualized_spend_cents": 1440000,
"renewal_date": "2027-01-15",
"status": "active",
"created_at": "2026-03-29T12:00:00.000Z"
}
}Retrieve a single subscription by its ID. Requires subscriptions:read. owner_name, owner_email and notes appear only when the key also holds subscriptions:contacts:read; the example shows the default shape without them.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/subscriptions/UUID{
"ok": true,
"data": {
"id": "uuid",
"vendor_name": "Slack",
"product_name": "Slack Business+",
"source": "integration",
"annualized_spend_cents": 1440000,
"renewal_date": "2027-01-15",
"status": "active",
"created_at": "2026-03-29T12:00:00.000Z",
"updated_at": "2026-04-02T09:15:00.000Z"
}
}Update fields on an existing subscription. Requires subscriptions:write. The response echoes owner_name, owner_email and notes only when the key also holds subscriptions:contacts:read; the example shows the default shape without them.
curl -X PATCH \
-H "Authorization: Bearer cb_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"annualized_spend_cents":1600000}' \
https://cubbie.com/api/v1/subscriptions/UUID{
"ok": true,
"data": {
"id": "uuid",
"vendor_name": "Slack",
"product_name": "Slack Business+",
"source": "integration",
"annualized_spend_cents": 1600000,
"renewal_date": "2027-01-15",
"status": "active",
"created_at": "2026-03-29T12:00:00.000Z",
"updated_at": "2026-05-12T08:00:00.000Z"
}
}Delete a subscription from your stack registry.
curl -X DELETE \
-H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/subscriptions/UUID{
"ok": true,
"data": { "deleted": true }
}Bulk import up to 500 subscriptions at once.
curl -X POST \
-H "Authorization: Bearer cb_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"items":[{"vendor_name":"Slack","product_name":"Slack Business+","annualized_spend_cents":1440000}]}' \
https://cubbie.com/api/v1/subscriptions/bulk{
"ok": true,
"data": { "created": 1, "failed": 0, "errors": [] }
}Trigger a full stack analysis for your organization. Returns gap analysis, benchmarks, and recommendations.
curl -X POST \
-H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/advisor/analyze{
"ok": true,
"data": {
"overallScore": 72,
"totalBenchmarked": 18,
"covered": 11,
"missing": 7,
"gaps": [...],
"strengths": [...],
"topPriorityActions": [...],
"estimatedAnnualSavingsCents": 240000,
"id": "uuid",
"recommendations": [...]
}
}Retrieve current recommendations. Supports optional query params: status, priority.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/advisor/recommendations{
"ok": true,
"data": {
"items": [
{
"id": "uuid",
"buyer_org_id": "uuid",
"gap_analysis_id": "uuid",
"category_slug": "project-management",
"category_name": "Project Management",
"recommendation_type": "missing_essential",
"priority": "high",
"headline": "Add a project management tool",
"rationale": "...",
"impact_summary": "...",
"estimated_roi": "...",
"recommended_products": [...],
"benchmark_data": { ... },
"status": "active",
"dismissed_at": null,
"acted_on_at": null,
"created_at": "2026-05-01T17:32:00.000Z",
"updated_at": "2026-05-01T17:32:00.000Z"
}
]
}
}Report usage data for a subscription (active users, licensed seats, utilization).
curl -X POST \
-H "Authorization: Bearer cb_live_xxxx" \
-H "Content-Type: application/json" \
-d '{"subscription_id":"UUID","active_users":42,"total_licensed_seats":50,"utilization_pct":84}' \
https://cubbie.com/api/v1/usage{
"ok": true,
"data": {
"id": "uuid",
"created_at": "2026-03-29T12:00:00.000Z"
}
}Renewal calendar: upcoming subscription renewals in a configurable window. Sorted ascending so the earliest-due rows surface first. Requires renewals:read. owner_name, owner_email and notes appear only when the key also holds subscriptions:contacts:read; the example shows the default shape without them.
curl -H "Authorization: Bearer cb_live_xxxx" \
"https://cubbie.com/api/v1/renewals/upcoming?days=90&status=active&includePast=false"{
"ok": true,
"data": {
"window": {
"startsAt": "2026-05-08T00:00:00.000Z",
"endsAt": "2026-08-06T23:59:59.999Z",
"days": 90,
"includePast": false
},
"items": [
{
"id": "uuid",
"vendor_name": "Acme",
"product_name": "Acme Pro",
"renewal_date": "2026-06-01",
"days_until_renewal": 24,
"annualized_spend_cents": 1200000,
"status": "active",
"source": "sso"
}
],
"totals": { "count": 1, "total_annualized_spend_cents": 1200000 }
}
}List Cubbie-powered partner program surfaces: hosted page URLs, embed URLs, script snippets, JSON URLs, state, and perk counts.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/partner-programs{
"ok": true,
"data": {
"items": [
{
"id": "uuid",
"name": "50Pros Agency Perks",
"slug": "50pros-agency-perks",
"state": "active",
"visibility": "public",
"program_type": "perks",
"access_mode": "open",
"perk_count": 24,
"urls": {
"hostedPageUrl": "https://perks.50pros.com",
"embedWidgetUrl": "https://perks.50pros.com/embed/perks/50pros-agency-perks",
"jsonApiUrl": "https://perks.50pros.com/api/partner-programs/public/50pros-agency-perks",
"scriptEmbedUrl": "https://perks.50pros.com/api/embed/v/v1/embed.js?slug=50pros-agency-perks"
},
"embed": {
"iframe": "<iframe src=...></iframe>",
"script": "<script async src=...></script>"
},
"updated_at": "2026-05-12T08:00:00.000Z"
}
]
}
}Retrieve one partner program's full configuration, surface URLs, and embed snippets.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/partner-programs/UUID{
"ok": true,
"data": {
"item": {
"id": "uuid",
"name": "50Pros Agency Perks",
"slug": "50pros-agency-perks",
"headline": "Software perks for your agency network",
"subheadline": "...",
"description": "...",
"audience_label": "Agencies",
"primary_cta_label": "View perk",
"state": "active",
"visibility": "public",
"program_type": "perks",
"access_mode": "open",
"allowed_email_domains": [],
"analytics_enabled": true,
"member_portal_enabled": false,
"referral_leads_enabled": false,
"script_embed_enabled": true,
"brand_config": { ... },
"selection_config": { ... },
"embed_config": { ... },
"perk_count": 24,
"urls": {
"hostedPageUrl": "https://perks.50pros.com",
"embedWidgetUrl": "https://perks.50pros.com/embed/perks/50pros-agency-perks",
"jsonApiUrl": "https://perks.50pros.com/api/partner-programs/public/50pros-agency-perks",
"scriptEmbedUrl": "https://perks.50pros.com/api/embed/v/v1/embed.js?slug=50pros-agency-perks"
},
"embed": {
"iframe": "<iframe src=...></iframe>",
"script": "<script async src=...></script>"
},
"created_at": "2026-04-01T10:00:00.000Z",
"updated_at": "2026-05-12T08:00:00.000Z"
}
}
}List the program's custom perks domains with verification state, DNS records, and provider status.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/partner-programs/UUID/domains{
"ok": true,
"data": {
"items": [
{
"id": "uuid",
"programId": "uuid",
"hostname": "perks.50pros.com",
"apexName": "50pros.com",
"status": "verified",
"isPrimary": true,
"verified": true,
"misconfigured": false,
"configuredBy": "CNAME",
"statusMessage": "...",
"verificationChallenges": [],
"dnsRecords": [
{
"type": "CNAME",
"hostname": "perks",
"value": "cname.vercel-dns.com",
"purpose": "routing"
}
],
"lastCheckedAt": "2026-05-12T08:00:00.000Z",
"verifiedAt": "2026-04-02T11:30:00.000Z",
"createdBy": "uuid",
"createdAt": "2026-04-01T10:05:00.000Z",
"updatedAt": "2026-05-12T08:00:00.000Z"
}
],
"provider": { "configured": true, "label": "Vercel" }
}
}List the program's content assets: FAQs, announcements, benefits, and resources.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/partner-programs/UUID/assets{
"ok": true,
"data": {
"items": [
{
"id": "uuid",
"programId": "uuid",
"kind": "faq",
"title": "How do I redeem a perk?",
"body": "...",
"ctaLabel": "Open perks page",
"ctaUrl": "https://perks.50pros.com",
"sortOrder": 0,
"isPublished": true,
"createdBy": "uuid",
"createdAt": "2026-04-01T10:05:00.000Z",
"updatedAt": "2026-04-01T10:05:00.000Z"
}
]
}
}List your vendor-admin connections. Returns connection metadata only -- credentials are never returned. Requires the vendor_admin:read scope.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/vendor-admin/connections{
"ok": true,
"data": {
"items": [
{
"id": "uuid",
"vendor_slug": "slack",
"vendor_label": "Slack",
"status": "connected",
"external_account_id": "T0123ABCD",
"scopes": ["admin.users:read"],
"last_sync_at": "2026-05-12T06:00:00.000Z",
"last_sync_status": "ok",
"last_sync_error": null,
"created_at": "2026-04-01T10:00:00.000Z",
"updated_at": "2026-05-12T06:00:00.000Z"
}
]
}
}Latest seat, usage, and billing snapshot per connected vendor. Optional query params: vendor_slug (restrict to one vendor) and limit (default 100, max 500). Requires the vendor_admin:read scope.
curl -H "Authorization: Bearer cb_live_xxxx" \
"https://cubbie.com/api/v1/vendor-admin/signals?vendor_slug=slack&limit=50"{
"ok": true,
"data": {
"items": [
{
"vendor_slug": "slack",
"vendor_label": "Slack",
"plan_tier": "Business+",
"total_licensed_seats": 50,
"active_user_count": 42,
"dormant_user_count": 8,
"measurement_window_days": 30,
"per_seat_cost_cents": 1800,
"annual_spend_cents": 1080000,
"renewal_date": "2027-01-15",
"account_manager_email": null,
"account_manager_name": null,
"raw_payload": { ... },
"observed_at": "2026-05-12T06:00:00.000Z"
}
]
}
}Current rightsizing recommendations computed from connected vendor signals, sorted by priority then estimated savings. Action filtering is applied: dismissed recommendations are hidden, snoozed ones are hidden until the snooze expires, and accepted ones return with action set. Requires the vendor_admin:read scope.
curl -H "Authorization: Bearer cb_live_xxxx" \
https://cubbie.com/api/v1/vendor-admin/recommendations{
"ok": true,
"data": {
"items": [
{
"vendor_slug": "slack",
"vendor_label": "Slack",
"kind": "downsize_seats",
"priority": 4,
"headline": "Reclaim 6 dormant Slack seats",
"body": "...",
"estimated_annual_savings_cents": 129600,
"details": { ... },
"details_hash": "3f9a...",
"action": null
}
]
}
}Cubbie Points wallet: current balance, pending credits awaiting reward fulfillment, and lifetime totals.
curl -H "Authorization: Bearer ck_xxxx" \
https://cubbie.com/api/v1/credits/balance{
"ok": true,
"data": {
"buyer_org_id": "uuid",
"available_cents": 12500,
"pending_cents": 3400,
"lifetime_earned_cents": 38900,
"lifetime_redeemed_cents": 0,
"updated_at": "2026-05-01T17:32:00.000Z"
}
}Cubbie Points ledger: append-only history of every credit issued, redeemed, reversed, expired, or adjusted. Returns the most recent entries, newest first; limit accepts 1-200 (default 50). There is no cursor-based pagination. kind is one of issue_pending, issue_available, redeem, reverse, expire, adjustment; state is pending, posted, or voided.
curl -H "Authorization: Bearer ck_xxxx" \
"https://cubbie.com/api/v1/credits/ledger?limit=50"{
"ok": true,
"data": {
"buyer_org_id": "uuid",
"entries": [
{
"id": "uuid",
"kind": "issue_available",
"state": "posted",
"amount_cents": 1200,
"note": "Marketplace order credit",
"created_at": "2026-05-01T17:32:00.000Z",
"posted_at": "2026-05-01T17:32:00.000Z",
"expires_at": null
}
]
}
}Error Handling
Errors return a non-2xx status code and a JSON body with the error details:
{
"ok": false,
"error": {
"message": "Unauthorized"
}
}An optional error.details field is included when extra context is available, for example field-level validation errors on 400 responses. It is omitted on 5xx responses.
| Status | Meaning |
|---|---|
400 | Invalid request body or parameters |
401 | Missing or invalid API key |
403 | Valid key but insufficient permissions |
404 | Resource not found |
429 | Rate limit exceeded |
500 | Internal server error |
Rate Limits
Default public v1 limits are 10 requests per second, 600 requests per minute, and 25,000 requests per day per API key. When a limit is exceeded, the API returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait before retrying. Higher quotas are available on request -- email [email protected] with your use case.
SDKs
REST is the stable public interface today. JavaScript, TypeScript, Python, Ruby, Go, PHP, and Java can all use the same HTTP API now; official packaged SDKs should be generated from the OpenAPI contract as the public developer platform matures. If you need an official package ahead of public release, email [email protected].
JavaScript / TypeScript quick start
const response = await fetch("https://cubbie.com/api/v1/subscriptions", {
headers: {
Authorization: `Bearer ${process.env.CUBBIE_API_KEY}`
}
});
if (!response.ok) {
throw new Error(await response.text());
}
console.log(await response.json());Python quick start
import os
import requests
response = requests.get(
"https://cubbie.com/api/v1/subscriptions",
headers={"Authorization": f"Bearer {os.environ['CUBBIE_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
print(response.json())Ruby quick start
require "json"
require "net/http"
require "uri"
uri = URI("https://cubbie.com/api/v1/subscriptions")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch('CUBBIE_API_KEY')}"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
raise response.body unless response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)| Language | Status |
|---|---|
| Node.js / TypeScript | REST available now; official SDK planned |
| Python | REST available now; official SDK planned |
| Ruby | REST available now; official SDK planned |
| Go / PHP / Java | REST available now; official SDK planned |
| HTTP (any client) | Available now |