GoliathDevelopersGet an API key
Reference/Billinggenerated from the gateway manifest

getBillingSummary

Read the organization's plan, subscription lifecycle, seat utilization, feature limits and credit balances.

POST/api/v1/callADMINreadruns as the key's owner
View as Markdown

Read the organization's plan, subscription lifecycle, seat utilization, feature limits and credit balances. Read-only. LIFECYCLE: answer "when does our trial end" and "are we set to cancel" from the dates, never from status alone: status: TRIALING is paired with trialEnds, and cancelAt is the scheduled cancel-at-period-end (null when nothing is scheduled). A deferred downgrade is the pendingPlanCode / pendingPlanIsAnnual / pendingPlanEffectiveAt trio (null when none): until pendingPlanEffectiveAt the org is STILL on planType, so report the current plan and the change date. isGrandfathered: a legacy price, so currentUnitAmountCents (the core plan) can differ from the published one. SEATS: compare extraSeats.seatsUsed against extraSeats.seatsCap DIRECTLY, which is already TOTAL capacity; never add extraSeatQuantity (the seats paid extra for, already inside it). Open seats = it − seatsUsed − live non-permanent invites (listTeamInvites isAlive, not isPermanent), min 0. featureLimits.seatsCap is a DIFFERENT number: plan-included seats only. extraSeats.unusedPaidSeats null means UNKNOWN, never zero. CREDITS: creditLedger.unitBalance is only the PURCHASED balance, so 0 there is not "none left". For what is left read planUsage, one row per credit type (AI_CREDITS and SMS_CREDITS included): plan planCap, usedThisPeriod, planRemaining, purchasedBalance, and available (spendable now; quote it), periodResetsAt, planCreditsLocked (only purchased credits spend). Before a skip trace, export or verification: checkBillingAction. 1 SMS credit = 1 outbound text segment; inbound is free. AI burn, sources, paywall: getAiCreditUsage (READ).

curl https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer $GOLIATH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operationId": "getBillingSummary",
    "variables": {}
  }'
import { GoliathClient } from '@goliath-data/sdk'

const goliath = new GoliathClient({
  apiKey: process.env.GOLIATH_API_KEY!,
  baseUrl: 'https://server.goliathdata.com',
})

const result = await goliath.billing.getBillingSummary()
const res = await fetch('https://server.goliathdata.com/api/v1/call', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.GOLIATH_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    operationId: 'getBillingSummary',
    variables: {}
  }),
})
const { data, errors } = await res.json()

Variables

None. Send "variables": {}.

Response

What comes back under data: a list shows as one entry, and a value as its type.

response shape
{
  "data": {
    "subscriptionQuery": {
      "getOrganizationBilling": {
        "id": "…",
        "planType": "RAMP",
        "status": "ACTIVE",
        "isAnnualPlan": true,
        "isGrandfathered": true,
        "currentUnitAmountCents": 0,
        "trialEnds": "2026-01-01T00:00:00.000Z",
        "cancelAt": "2026-01-01T00:00:00.000Z",
        "pendingPlanCode": "RAMP",
        "pendingPlanIsAnnual": true,
        "pendingPlanEffectiveAt": "2026-01-01T00:00:00.000Z",
        "featureLimits": {
          "seatsCap": 0,
          "skiptraceCap": 0,
          "emailVerificationCap": 0,
          "exportPropertiesCap": 0,
          "aiCreditsCap": 0,
          "smsCreditsCap": 0,
          "phoneNumbersCap": 0,
          "callingMinutesCap": 0
        },
        "extraSeats": {
          "seatsCap": 0,
          "seatsUsed": 0,
          "extraSeatQuantity": 0,
          "unusedPaidSeats": 0,
          "unusedPaidSeatsReleaseAt": "2026-01-01T00:00:00.000Z"
        },
        "creditLedger": [
          {
            "type": "EXPORT_PROPERTIES",
            "unitBalance": 0
          }
        ],
        "planUsage": [
          {
            "type": "EXPORT_PROPERTIES",
            "planCap": 0,
            "usedThisPeriod": 0,
            "planRemaining": 0,
            "planCreditsLocked": true,
            "purchasedBalance": 0,
            "available": 0,
            "periodResetsAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      }
    }
  }
}

Errors

Behaviour

A read. It rejects an Idempotency-Key header with 400 bad_request.