{"openapi":"3.1.0","info":{"title":"Bullion API","version":"1.0.0","summary":"Gold spot prices as a simple JSON REST API.","description":"Live and historical gold prices in 30 currencies. Responses are served from a cache refreshed hourly by a scheduled job; API requests never call upstream providers. Authenticate price-data requests with the canonical and preferred X-API-Key header, or use the api_key query parameter as a fallback when a client cannot set custom headers. Query credentials may appear in browser history, copied URLs, referrers, intermediary infrastructure, and logs. Query authentication does not enable cross-origin browser fetch; CORS remains separate. If both transports are supplied, they must match; differing values return HTTP 401 with code conflicting_credentials. Free and Pro are for non-commercial use only. Enterprise includes commercial display and integration. Raw or substantially equivalent data redistribution and resale are excluded from all standard plans.","termsOfService":"https://bullionapi.dev/terms","contact":{"name":"Bullion API","url":"https://bullionapi.dev","email":"hello@bullionapi.dev"}},"servers":[{"url":"https://api.bullionapi.dev"}],"security":[{"ApiKeyAuth":[]},{"ApiKeyQuery":[]}],"tags":[{"name":"prices","description":"Gold price data (API key required)"},{"name":"macro","description":"Latest macroeconomic observations (API key required)"},{"name":"reserves","description":"Pro and Enterprise annual central-bank reserve data"},{"name":"portfolio","description":"Private account-owned gold portfolio settings"},{"name":"account","description":"Account-scoped usage (session cookie)"},{"name":"meta","description":"Service metadata (public)"}],"paths":{"/v1/latest":{"get":{"tags":["prices"],"security":[{"ApiKeyAuth":[]},{"ApiKeyQuery":[]}],"summary":"Latest gold spot price","description":"Returns the most recent gold spot price and the FX rates needed to convert it into the requested base currency. Prices default to troy ounces. Pass unit=gram, unit=kilogram, or unit=troy_oz (including their documented aliases) to choose the response unit. Cached for 1 hour. Usage increments after API-key and quota checks but before endpoint validation.","operationId":"getLatest","parameters":[{"$ref":"#/components/parameters/Currency"},{"$ref":"#/components/parameters/Unit"}],"responses":{"200":{"description":"Latest prices, served from cache.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LatestResponse"}}}},"400":{"description":"The requested unit is not supported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LatestBadRequestError"},"example":{"status":"error","error":{"code":"invalid_unit","message":"unit must be one of: gram, g, kilogram, kg, troy_oz, toz"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/EmailNotVerified"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["prices"],"summary":"Not supported — read-only API","operationId":"postLatestNotAllowed","responses":{"405":{"$ref":"#/components/responses/MethodNotAllowed"}}}},"/v1/carat":{"get":{"tags":["prices"],"security":[{"ApiKeyAuth":[]},{"ApiKeyQuery":[]}],"summary":"Cached gold karat prices per gram","description":"Returns cached gold prices per gram for the approved karat keys. Without date, the current cached gold row is used. With date=YYYY-MM-DD, the final cached gold observation within that UTC day is used. This is a database-only reader and never calls an upstream provider or bridges currencies.","operationId":"getCarat","parameters":[{"$ref":"#/components/parameters/CaratCurrency"},{"$ref":"#/components/parameters/CaratDate"}],"responses":{"200":{"description":"Cached gold karat prices per gram.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaratResponse"}}}},"400":{"description":"The currency or date query parameter is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaratBadRequestError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/EmailNotVerified"},"404":{"description":"No cached gold row exists for the currency or requested UTC day.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaratNoDataError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"description":"The cached gold data could not be read.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"post":{"tags":["prices"],"summary":"Not supported — read-only API","operationId":"postCaratNotAllowed","responses":{"405":{"$ref":"#/components/responses/MethodNotAllowed"}}}},"/v1/timeseries":{"get":{"tags":["prices"],"security":[{"ApiKeyAuth":[]},{"ApiKeyQuery":[]}],"summary":"Historical daily gold closes","description":"Returns daily gold closes across a date range. Only cached dates are included in `rates`; scheduled refresh and backfill jobs populate the cache. Prices default to troy ounces; pass unit=gram, unit=kilogram, or unit=troy_oz (including their documented aliases) to choose the response unit.","operationId":"getTimeseries","parameters":[{"$ref":"#/components/parameters/Currency"},{"$ref":"#/components/parameters/StartDate"},{"$ref":"#/components/parameters/EndDate"},{"$ref":"#/components/parameters/Unit"}],"responses":{"200":{"description":"Daily closes keyed by date. Dates with no cached row are omitted.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeseriesResponse"}}}},"400":{"description":"Invalid date, range, or unit query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeseriesBadRequestError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/EmailNotVerified"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/change":{"get":{"tags":["prices"],"security":[{"ApiKeyAuth":[]},{"ApiKeyQuery":[]}],"summary":"Gold price change between cached observations","description":"Returns the absolute and percentage change in gold between the final cached observation in two requested UTC days. Use either start_date and end_date together, or one rolling date_type: yesterday, week, month, or year. The endpoint is a database-only reader and never calls upstream providers. The start price is the percentage-change baseline; a zero baseline returns invalid_change_baseline.","operationId":"getChange","parameters":[{"$ref":"#/components/parameters/Currency"},{"$ref":"#/components/parameters/ChangeStartDate"},{"$ref":"#/components/parameters/ChangeEndDate"},{"$ref":"#/components/parameters/ChangeDateType"}],"responses":{"200":{"description":"Absolute and percentage change for cached gold observations.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeResponse"}}}},"400":{"description":"Invalid date, date type, conflicting forms, or range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeBadRequestError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/EmailNotVerified"},"404":{"description":"One or both requested UTC days have no cached gold observation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeNoDataError"}}}},"422":{"description":"The cached start price cannot be used as a percentage baseline.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeBaselineError"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["prices"],"summary":"Not supported — read-only API","operationId":"postChangeNotAllowed","responses":{"405":{"$ref":"#/components/responses/MethodNotAllowed"}}}},"/v1/rates/{region}":{"get":{"tags":["macro"],"security":[{"ApiKeyAuth":[]},{"ApiKeyQuery":[]}],"summary":"Latest stored US, UK, and euro-area macro rates","description":"Returns the latest stored policy, yield, and inflation observation for each available series in the requested region. Policy rates, monthly yield averages, breakevens, and CPI can have independent observation periods. Every observation includes its upstream series ID and source attribution. U.S. Treasury and European Central Bank AAA yields use valid daily observations from complete calendar months; breakevens use matched nominal and real dates; BLS CPI-U is the not-seasonally-adjusted CUUR0000SA0 series; euro-area HICP uses the metadata-verified all-items annual-rate series and ECB Consumer Expectations Survey values are weighted-median survey expectations, not market-implied. the euro-area response identifies its geography as `euro_area`. UK policy uses Bank of England IUDBEDR Bank Rate observations and UK inflation uses the Office for National Statistics D7G7 CPI annual rate. BoE and ONS data are attributed under the Open Government Licence: https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/. UK gilt data also includes BoE nominal and real zero-coupon spot yields plus RPI-linked implied inflation at 2Y, 5Y, 10Y, and 30Y tenors using official month-end archive dates and method month_end. European Central Bank statistics are freely available for reuse when accurately reproduced and cited. Free, Pro, and Enterprise keys receive the same data contract; only their existing monthly quota limits differ. API requests read the database and never call upstream sources.","operationId":"getMacroRates","parameters":[{"$ref":"#/components/parameters/MacroRegion"}],"responses":{"200":{"description":"Latest policy, yield, and inflation observations with per-observation provenance.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MacroRatesResponse"}}}},"400":{"description":"The requested macro region is not supported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MacroBadRequestError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/EmailNotVerified"},"429":{"$ref":"#/components/responses/QuotaExceeded"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"description":"No stored observations are available for the requested region.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"post":{"tags":["macro"],"summary":"Not supported — read-only API","operationId":"postMacroRatesNotAllowed","responses":{"405":{"$ref":"#/components/responses/MethodNotAllowed"}}}},"/v1/central-bank-reserves":{"get":{"tags":["reserves"],"security":[{"ApiKeyAuth":[]},{"ApiKeyQuery":[]}],"summary":"Annual central-bank reserve values and gold share","description":"Annual reserve valuations for Pro and Enterprise accounts from World Bank, World Development Indicators, whose underlying provider is International Monetary Fund, International Financial Statistics. Bullion API derives gold reserve value, gold share, and consecutive-year value change from cached observations. Annual value change combines holdings changes, gold-price movement, and revisions; it does not measure tonnes bought or sold.","operationId":"getCentralBankReserves","parameters":[{"$ref":"#/components/parameters/CountryIso2"},{"$ref":"#/components/parameters/StartYear"},{"$ref":"#/components/parameters/EndYear"}],"responses":{"200":{"description":"Complete annual reserve observations served from the automated cache.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CentralBankReservesResponse"}}}},"400":{"description":"Invalid country or year parameters. The request still consumes quota.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CentralBankBadRequestError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Email verification is required, followed by an active Pro or Enterprise plan.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/EmailNotVerifiedError"},{"$ref":"#/components/schemas/PlanRequiredError"}]},"examples":{"email_not_verified":{"value":{"status":"error","error":{"code":"email_not_verified","message":"Verify your email address before using the API"}}},"plan_required":{"value":{"status":"error","error":{"code":"plan_required","message":"This endpoint requires one of these plans: pro, enterprise","required_plans":["pro","enterprise"],"plan":"free"}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"description":"The automated cache has no complete observations.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"status":"error","error":{"code":"data_unavailable","message":"Central-bank reserve data is not available"}}}}}}},"post":{"tags":["reserves"],"summary":"Not supported — read-only API","operationId":"postCentralBankReservesNotAllowed","responses":{"405":{"$ref":"#/components/responses/MethodNotAllowed"}}}},"/v1/portfolio":{"get":{"tags":["portfolio"],"security":[{"ApiKeyAuth":[]}],"summary":"Read owned gold portfolio settings and empty summary","description":"Requires portfolio read permission and accepts X-API-Key only. Query-string credentials are not accepted. The request retains the rolling per-key and source-IP abuse limits but does not increment the monthly market-data quota. Until transactions and valuation ship, exact decimal summary values are zero strings and valuation is explicitly unavailable.","operationId":"getPortfolio","responses":{"200":{"description":"Owned portfolio settings and an empty exact-decimal summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioResponse"}}}},"401":{"description":"The X-API-Key header is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key owner is unverified or the key lacks portfolio read permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"insufficient_scope":{"value":{"status":"error","error":{"code":"insufficient_scope","message":"API key lacks the required portfolio scope"}}},"email_not_verified":{"value":{"status":"error","error":{"code":"email_not_verified","message":"Verify your email address before using the API"}}}}}}},"404":{"description":"The account does not have a configured portfolio.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"status":"error","error":{"code":"portfolio_not_found","message":"Portfolio not found"}}}}},"429":{"$ref":"#/components/responses/PortfolioRateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"put":{"tags":["portfolio"],"security":[{"ApiKeyAuth":[]}],"summary":"Create or update owned gold portfolio settings","description":"Requires portfolio write permission and accepts X-API-Key only. Write permission always includes read. The reporting currency can change while the ledger is empty. The request retains abuse limits but does not increment the monthly market-data quota.","operationId":"putPortfolio","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioSettingsInput"}}}},"responses":{"200":{"description":"Created or updated portfolio settings and empty summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioResponse"}}}},"400":{"description":"The reporting currency is missing or unsupported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"status":"error","error":{"code":"invalid_currency","message":"reporting_currency must be a supported currency"}}}}},"401":{"description":"The X-API-Key header is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"The key owner is unverified or the key lacks portfolio write permission.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"status":"error","error":{"code":"insufficient_scope","message":"API key lacks the required portfolio scope"}}}}},"429":{"$ref":"#/components/responses/PortfolioRateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/usage":{"get":{"tags":["account"],"summary":"Plan, quota and recent requests for the signed-in user","description":"Authenticated via session cookie (NOT X-API-Key) so the dashboard can call it directly without storing an API key client-side. This spec is informational for this endpoint: browsers obtain the cookie by signing in at https://bullionapi.dev/login.","operationId":"getUsage","security":[{"CookieAuth":[]}],"responses":{"200":{"description":"Current plan, monthly quota state and the 50 most recent requests.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"401":{"description":"Not signed in.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"status":"error","error":{"code":"unauthenticated","message":"Not signed in"}}}}},"500":{"$ref":"#/components/responses/InternalError"}}}},"/health":{"get":{"tags":["meta"],"summary":"Service health","description":"Public, no auth. Reports database reachability and cache freshness. Returns 503 when the cache has not been refreshed within the staleness budget.","operationId":"getHealth","security":[],"responses":{"200":{"description":"Healthy: database reachable and cache fresh.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"503":{"description":"Degraded: database unreachable or cache stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key created in the dashboard, prefixed `bullion_`."},"ApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key","description":"Fallback API key for clients that cannot set custom headers. Query credentials can be exposed by URLs; prefer ApiKeyAuth whenever possible."},"CookieAuth":{"type":"apiKey","in":"cookie","name":"better-auth.session_token","description":"Session cookie set on sign-in. Over HTTPS the name is prefixed: `__Secure-better-auth.session_token`."}},"parameters":{"Currency":{"name":"currency","in":"query","required":false,"schema":{"type":"string","default":"USD","example":"EUR"},"description":"ISO 4217 base currency, case-insensitive. Supported: USD, EUR, GBP, JPY, CHF, CAD, AUD, NZD, CNY, HKD, SGD, SEK, NOK, DKK, PLN, CZK, HUF, TRY, ZAR, INR, KRW, BRL, MXN, AED, SAR, ILS, THB, IDR, MYR, PHP. Any other code is accepted and returns 200 with empty `metals` / `currencies` maps until that currency is seeded."},"CaratCurrency":{"name":"currency","in":"query","required":false,"schema":{"type":"string","pattern":"^[A-Za-z]{3}$","default":"USD","example":"EUR"},"description":"Three-letter ISO 4217 currency code, case-insensitive. The request succeeds only when that currency has cached gold data."},"CaratDate":{"name":"date","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-10"},"description":"Optional exact UTC day. The final cached gold observation in that day is used; malformed or impossible dates return 400 invalid_date."},"Unit":{"name":"unit","in":"query","required":false,"schema":{"type":"string","enum":["gram","g","kilogram","kg","troy_oz","toz"],"default":"toz"},"description":"Output mass unit. Omit or leave empty for the legacy toz response. gram and g return grams; kilogram and kg return kilograms; troy_oz and toz return troy ounces. Values are converted to eight decimal places. Other non-empty values return 400 invalid_unit."},"StartDate":{"name":"start_date","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-01"},"description":"First day to include (inclusive), YYYY-MM-DD."},"EndDate":{"name":"end_date","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-31"},"description":"Last day to include (inclusive), YYYY-MM-DD. Must be >= start_date."},"ChangeStartDate":{"name":"start_date","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-01"},"description":"First UTC day to compare, used together with end_date."},"ChangeEndDate":{"name":"end_date","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-01-02"},"description":"Last UTC day to compare, used together with start_date."},"ChangeDateType":{"name":"date_type","in":"query","required":false,"schema":{"type":"string","enum":["yesterday","week","month","year"]},"description":"Rolling UTC window. yesterday is 1 day, week is 7 days, month is 30 days, and year is 365 days. Use instead of the explicit date pair."},"CountryIso2":{"name":"country","in":"query","required":false,"schema":{"type":"string","pattern":"^[A-Za-z]{2}$","example":"GB"},"description":"ISO 3166-1 alpha-2 country code, case-insensitive."},"StartYear":{"name":"start","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}$","example":"2020"},"description":"First observation year to include (inclusive)."},"EndYear":{"name":"end","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}$","example":"2025"},"description":"Last observation year to include (inclusive). Must be >= start."},"MacroRegion":{"name":"region","in":"path","required":true,"schema":{"type":"string","enum":["us","eu","uk"],"example":"us"},"description":"Macro region code. Use `us`, `uk`, or `eu` for the United States, United Kingdom, or euro area."}},"responses":{"Unauthorized":{"description":"Missing, conflicting, or invalid API key credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"examples":{"missing":{"value":{"status":"error","error":{"code":"missing_api_key","message":"Missing API key"}}},"conflict":{"value":{"status":"error","error":{"code":"conflicting_credentials","message":"Conflicting API key credentials"}}},"invalid":{"value":{"status":"error","error":{"code":"invalid_api_key","message":"Invalid or revoked API key"}}}}}}},"EmailNotVerified":{"description":"The API-key owner must verify their email address before accessing price data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"status":"error","error":{"code":"email_not_verified","message":"Verify your email address before using the API"}}}}},"QuotaExceeded":{"description":"Monthly quota reached. Quota resets on the 1st of next month, 00:00 UTC.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}},"retry-after":{"description":"Seconds until the quota resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceededError"},"example":{"status":"error","error":{"code":"quota_exceeded","message":"Your monthly usage limit has been reached. Please upgrade your subscription plan.","plan":"free","used":30,"limit":30,"reset_at":"2026-08-01T00:00:00.000Z"}}}}},"TooManyRequests":{"description":"The API-key rolling window or monthly quota has been exceeded.","headers":{"x-ratelimit-limit":{"description":"Your plan's monthly request cap.","schema":{"type":"integer","example":30}},"x-ratelimit-used":{"description":"Requests used this month, including this one.","schema":{"type":"integer","example":1}},"x-ratelimit-remaining":{"description":"Requests remaining this month.","schema":{"type":"integer","example":29}},"x-ratelimit-plan":{"description":"The plan the quota is enforced against.","schema":{"type":"string","enum":["free","pro","enterprise"],"example":"free"}},"x-ratelimit-reset":{"description":"When the quota resets (1st of next month, 00:00 UTC).","schema":{"type":"string","format":"date-time"}},"X-API-CURRENT":{"description":"Compatibility alias for x-ratelimit-used.","schema":{"type":"integer","example":1}},"X-API-QUOTA":{"description":"Compatibility alias for x-ratelimit-limit.","schema":{"type":"integer","example":30}},"retry-after":{"description":"Seconds until the applicable limit resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/QuotaExceededError"},{"$ref":"#/components/schemas/RateLimitedError"}]},"examples":{"rate_limited":{"value":{"status":"error","error":{"code":"rate_limited","message":"Rate limit exceeded"}}},"quota_exceeded":{"value":{"status":"error","error":{"code":"quota_exceeded","message":"Your monthly usage limit has been reached. Please upgrade your subscription plan."}}}}}}},"PortfolioRateLimited":{"description":"The API key has exceeded its rolling request window.","headers":{"retry-after":{"description":"Seconds until the per-key rolling limit resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedError"},"example":{"status":"error","error":{"code":"rate_limited","message":"Rate limit exceeded"}}}}},"MethodNotAllowed":{"description":"The API is read-only; writes are not supported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"status":"error","error":{"code":"method_not_allowed","message":"Method not allowed"}}}}},"InternalError":{"description":"Server configuration error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"},"example":{"status":"error","error":{"code":"config_error","message":"DATABASE_URL not set"}}}}}},"schemas":{"PortfolioSettingsInput":{"type":"object","additionalProperties":false,"required":["reporting_currency"],"properties":{"reporting_currency":{"type":"string","enum":["USD","EUR","GBP","JPY","CHF","CAD","AUD","NZD","CNY","HKD","SGD","SEK","NOK","DKK","PLN","CZK","HUF","TRY","ZAR","INR","KRW","BRL","MXN","AED","SAR","ILS","THB","IDR","MYR","PHP"],"example":"GBP"}}},"PortfolioSettings":{"type":"object","additionalProperties":false,"required":["id","metal","reporting_currency","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"metal":{"type":"string","const":"gold"},"reporting_currency":{"type":"string","enum":["USD","EUR","GBP","JPY","CHF","CAD","AUD","NZD","CNY","HKD","SGD","SEK","NOK","DKK","PLN","CZK","HUF","TRY","ZAR","INR","KRW","BRL","MXN","AED","SAR","ILS","THB","IDR","MYR","PHP"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"PortfolioSummary":{"type":"object","additionalProperties":false,"required":["gold_quantity_grams","cost_basis","realised_pnl","valuation"],"properties":{"gold_quantity_grams":{"type":"string","example":"0.000000000000000"},"cost_basis":{"type":"string","example":"0.00000000"},"realised_pnl":{"type":"string","example":"0.00000000"},"valuation":{"type":"object","additionalProperties":false,"required":["status","current_value","unrealised_pnl","price_timestamp"],"properties":{"status":{"type":"string","const":"unavailable"},"current_value":{"type":"null"},"unrealised_pnl":{"type":"null"},"price_timestamp":{"type":"null"}}}}},"PortfolioResponse":{"type":"object","additionalProperties":false,"required":["status","portfolio","summary"],"properties":{"status":{"type":"string","const":"success"},"portfolio":{"$ref":"#/components/schemas/PortfolioSettings"},"summary":{"$ref":"#/components/schemas/PortfolioSummary"}}},"LatestResponse":{"type":"object","required":["status","currency","unit","metals","currencies","timestamps"],"properties":{"status":{"type":"string","const":"success"},"currency":{"type":"string","description":"Base currency of the response."},"unit":{"type":"string","enum":["toz","troy_oz","gram","kilogram"],"description":"Normalized output mass unit. Legacy default is `toz`; explicit troy-ounce requests return `troy_oz`."},"metals":{"type":"object","additionalProperties":{"type":"number"},"description":"Spot prices keyed by metal. Gold only at launch: `{ \"gold\": 4527.86 }`.","example":{"gold":4527.86}},"currencies":{"type":"object","additionalProperties":{"type":"number"},"description":"FX rates from the base currency keyed by target currency.","example":{"EUR":0.9134,"GBP":0.7783,"JPY":154.22,"CAD":1.3715}},"timestamps":{"type":"object","required":["metal","currency"],"properties":{"metal":{"type":"string","description":"ISO 8601 fetch time of the metal price, or empty string if unseeded."},"currency":{"type":"string","description":"ISO 8601 fetch time of the FX rates, or empty string if unseeded."}}}}},"CaratResponse":{"type":"object","additionalProperties":false,"required":["status","currency","unit","as_of","karats"],"properties":{"status":{"type":"string","const":"success"},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"unit":{"type":"string","const":"gram"},"as_of":{"type":"string","format":"date-time"},"karats":{"type":"object","additionalProperties":false,"required":["24k","23k","22k","21.6k","21k","18k","16k","14k","12k","10k","9k","8k","6k"],"properties":{"24k":{"type":"number"},"23k":{"type":"number"},"22k":{"type":"number"},"21.6k":{"type":"number"},"21k":{"type":"number"},"18k":{"type":"number"},"16k":{"type":"number"},"14k":{"type":"number"},"12k":{"type":"number"},"10k":{"type":"number"},"9k":{"type":"number"},"8k":{"type":"number"},"6k":{"type":"number"}}}}},"TimeseriesResponse":{"type":"object","required":["status","currency","unit","start_date","end_date","rates"],"properties":{"status":{"type":"string","const":"success"},"currency":{"type":"string"},"unit":{"type":"string","enum":["toz","troy_oz","gram","kilogram"],"description":"Normalized output mass unit. Omitted or empty input returns legacy `toz`."},"start_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"end_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"rates":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimeseriesDay"},"description":"Daily closes keyed by YYYY-MM-DD. Only cached dates are present."}}},"ChangeResponse":{"type":"object","additionalProperties":false,"required":["status","currency","metal","start_date","end_date","start_price","end_price","change","change_pct"],"properties":{"status":{"type":"string","const":"success"},"currency":{"type":"string"},"metal":{"type":"string","const":"gold"},"start_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"end_date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"start_price":{"type":"number"},"end_price":{"type":"number"},"change":{"type":"number","description":"End price minus start price, rounded to eight decimals."},"change_pct":{"type":"number","description":"Percentage change relative to start price, rounded to four decimals."}}},"TimeseriesDay":{"type":"object","required":["currencies","date","metals"],"properties":{"currencies":{"type":"object","additionalProperties":{"type":"number"},"example":{"EUR":0.9134,"GBP":0.7783}},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"metals":{"type":"object","additionalProperties":{"type":"number"},"example":{"gold":3320.1}}}},"MacroRatesResponse":{"type":"object","required":["status","region","policy","yields","inflation"],"properties":{"status":{"type":"string","const":"success"},"region":{"type":"string","enum":["us","euro_area","uk"]},"policy":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MacroRateObservation"}},"yields":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MacroRateObservation"}},"inflation":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/MacroRateObservation"}}}},"MacroRateObservation":{"type":"object","required":["series_id","value","unit","observation_period","method","source_series_id","source_id","attribution","fetched_at"],"properties":{"series_id":{"type":"string"},"value":{"type":"number"},"unit":{"type":"string","example":"percent"},"observation_period":{"type":"string","format":"date"},"method":{"type":"string","enum":["latest","monthly_average","month_end","derived_monthly_average","survey_expectation"]},"source_series_id":{"type":"string"},"source_id":{"type":"string"},"attribution":{"type":"string"},"fetched_at":{"type":"string","format":"date-time"}}},"MacroBadRequestError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_region"]},"message":{"type":"string"}}}}},"CentralBankReservesResponse":{"type":"object","required":["status","source","methodology","coverage","reserves"],"properties":{"status":{"type":"string","const":"success"},"source":{"$ref":"#/components/schemas/CentralBankReserveSource"},"methodology":{"$ref":"#/components/schemas/CentralBankReserveMethodology"},"coverage":{"$ref":"#/components/schemas/CentralBankReserveCoverage"},"reserves":{"type":"array","items":{"$ref":"#/components/schemas/CentralBankReserveObservation"}}}},"CentralBankReserveSource":{"type":"object","required":["name","underlying_provider","url","terms_url","available_free_of_charge"],"properties":{"name":{"type":"string","const":"World Bank, World Development Indicators"},"underlying_provider":{"type":"string","const":"International Monetary Fund, International Financial Statistics"},"url":{"type":"string","const":"https://data.worldbank.org/"},"terms_url":{"type":"string","const":"https://data.worldbank.org/summary-terms-of-use"},"available_free_of_charge":{"type":"boolean","const":true}}},"CentralBankReserveMethodology":{"type":"object","required":["gold_reserve_value_usd","annual_gold_value_change_usd","transformation_notice","warning"],"properties":{"gold_reserve_value_usd":{"type":"string","const":"total reserves including gold minus total reserves excluding gold"},"annual_gold_value_change_usd":{"type":"string","const":"current derived gold reserve value minus the prior calendar year"},"transformation_notice":{"type":"string","const":"Bullion API derives gold reserve values, shares, and annual value changes."},"warning":{"type":"string","const":"Annual value changes combine holdings changes, gold-price movement, and revisions and do not measure tonnes bought or sold."}}},"CentralBankReserveCoverage":{"type":"object","required":["countries","start_year","end_year","source_updated_at","fetched_at"],"properties":{"countries":{"type":"integer","minimum":0},"start_year":{"type":["integer","null"]},"end_year":{"type":["integer","null"]},"source_updated_at":{"type":"string","format":"date"},"fetched_at":{"type":"string","format":"date-time"}}},"CentralBankReserveObservation":{"type":"object","required":["country","country_iso3","country_name","as_of_year","total_reserves_usd","reserves_excluding_gold_usd","gold_reserve_value_usd","gold_share_pct","annual_gold_value_change_usd","data_quality"],"properties":{"country":{"type":"string","pattern":"^[A-Z]{2}$"},"country_iso3":{"type":"string","pattern":"^[A-Z]{3}$"},"country_name":{"type":"string"},"as_of_year":{"type":"integer"},"total_reserves_usd":{"type":"number"},"reserves_excluding_gold_usd":{"type":"number"},"gold_reserve_value_usd":{"type":["number","null"]},"gold_share_pct":{"type":["number","null"]},"annual_gold_value_change_usd":{"type":["number","null"]},"data_quality":{"type":["string","null"],"enum":["inconsistent_source_values",null]}}},"CentralBankBadRequestError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_country","invalid_year","invalid_range"]},"message":{"type":"string"}}}}},"EmailNotVerifiedError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","const":"email_not_verified"},"message":{"type":"string"}}}}},"PlanRequiredError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","additionalProperties":false,"required":["code","message","required_plans","plan"],"properties":{"code":{"type":"string","const":"plan_required"},"message":{"type":"string"},"required_plans":{"type":"array","const":["pro","enterprise"]},"plan":{"type":"string","enum":["free","pro","enterprise"]}}}}},"UsageResponse":{"type":"object","required":["plan","limit","used","remaining","reset_at","subscription","recent","email","email_verified"],"properties":{"plan":{"type":"string","enum":["free","pro","enterprise"]},"limit":{"type":"integer","description":"Monthly request cap for the plan."},"used":{"type":"integer","description":"Requests used this month."},"remaining":{"type":"integer"},"reset_at":{"type":"string","format":"date-time"},"subscription":{"type":"object","required":["status"],"properties":{"status":{"type":["string","null"],"description":"Stripe subscription status, or null on the free plan."}}},"recent":{"type":"array","description":"The 50 most recent API requests, newest first.","items":{"$ref":"#/components/schemas/RecentRequest"}},"email":{"type":"string","format":"email"},"email_verified":{"type":"boolean"}}},"RecentRequest":{"type":"object","required":["endpoint","method","status_code","response_ms","requested_at"],"properties":{"endpoint":{"type":"string","example":"/v1/latest?currency=USD"},"method":{"type":"string","example":"GET"},"status_code":{"type":"integer","example":200},"response_ms":{"type":"integer"},"requested_at":{"type":"string","format":"date-time"}}},"HealthResponse":{"type":"object","required":["status","db_reachable","last_refresh_at","currencies_with_data"],"properties":{"status":{"type":"string","enum":["ok","degraded"]},"db_reachable":{"type":"boolean"},"last_refresh_at":{"type":["string","null"],"format":"date-time","description":"ISO 8601 time of the last successful cache refresh."},"currencies_with_data":{"type":"array","items":{"type":"string"},"description":"Base currencies with at least one cached metal price."}}},"ErrorEnvelope":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["config_error","billing_state_conflict","annual_billing_unavailable","billing_interval_change_conflict","billing_interval_change_expired","billing_interval_change_failed","billing_interval_change_invalid","billing_interval_change_processing","billing_cancellation_conflict","billing_cancellation_failed","billing_cancellation_invalid","conflicting_credentials","data_unavailable","email_not_verified","invalid_api_key","invalid_country","invalid_currency","invalid_date","invalid_range","invalid_region","invalid_unit","invalid_year","method_not_allowed","missing_api_key","missing_params","no_data","plan_required","quota_exceeded","rate_limited","unauthenticated","api_key_not_found","insufficient_scope","invalid_portfolio_permission","portfolio_not_found"],"description":"Machine-readable error code."},"message":{"type":"string","description":"Human-readable message."}},"additionalProperties":true}}},"TimeseriesBadRequestError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["missing_params","invalid_date","invalid_range","invalid_unit"]},"message":{"type":"string"}}}}},"ChangeBadRequestError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["missing_params","conflicting_params","invalid_date","invalid_range","invalid_date_type"]},"message":{"type":"string"}}}}},"ChangeNoDataError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","const":"no_change_data"},"message":{"type":"string"}}}}},"ChangeBaselineError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","const":"invalid_change_baseline"},"message":{"type":"string"}}}}},"LatestBadRequestError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","const":"invalid_unit"},"message":{"type":"string"}}}}},"CaratBadRequestError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_currency","invalid_date"]},"message":{"type":"string"}}}}},"CaratNoDataError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","const":"no_data"},"message":{"type":"string"}}}}},"QuotaExceededError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","additionalProperties":false,"required":["code","message","plan","used","limit","reset_at"],"properties":{"code":{"type":"string","const":"quota_exceeded"},"message":{"type":"string","example":"Your monthly usage limit has been reached. Please upgrade your subscription plan."},"plan":{"type":"string","enum":["free","pro","enterprise"]},"used":{"type":"integer"},"limit":{"type":"integer"},"reset_at":{"type":"string","format":"date-time"}}}}},"RateLimitedError":{"type":"object","additionalProperties":false,"required":["status","error"],"properties":{"status":{"type":"string","const":"error"},"error":{"type":"object","additionalProperties":false,"required":["code","message"],"properties":{"code":{"type":"string","const":"rate_limited"},"message":{"type":"string","example":"Rate limit exceeded"}}}}}}}}