{"openapi":"3.1.1","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"Blueberries Public Dashboard API","version":"1.0.0","description":"D&I dashboard data and filters, account and key management, health checks, and documentation downloads. Examples contain no issued credentials or customer data.","x-documentation-version":"2.1.0"},"servers":[{"url":"/","description":"Same origin as this OpenAPI document"}],"tags":[{"name":"Retail SPINS","description":"SPINS metrics by product, size, geography, and growing method."},{"name":"USDA Imports","description":"Pre-aggregated import volumes by country, HS code, and berry category."},{"name":"USDA FAS Exports","description":"Exports (flow_type Export) by country, month, and berry category."},{"name":"USDA AMS","description":"FOB prices and movement in lb, aggregated by period and origin."},{"name":"Authentication","description":"Portal login, availability, and logout."},{"name":"Account portal","description":"Session, profile, and personal API key management."},{"name":"Health","description":"Service probes."},{"name":"Documentation","description":"Machine-readable documentation downloads."}],"externalDocs":{"description":"Human-readable guide with examples and a data dictionary.","url":"/docs"},"paths":{"/v1/dashboards/retail":{"get":{"operationId":"getRetailDashboard","tags":["Retail SPINS"],"summary":"Get Retail SPINS","description":"SPINS metrics by product, size, geography, and growing method. Periods 28/84/182/365 map to 4/12/26/52 Weeks in the aggregate table. Trends use 28/84/182/364 days aligned to Saturday. Shares always use lb. YoY for Units also uses lb. Units is estimated by dividing by the numeric size, as in the original SQL. fresh_frozen affects size comparisons and weekly series; Fresh and Frozen KPIs continue to return their categories separately. base_size_filter is applied by SQL but is not echoed in appliedFilters by the original adapter. Measures may be numbers or decimal strings depending on the underlying BigQuery type (the SDK preserves NUMERIC/BIGNUMERIC precision). The actual source schema still requires validation; examples use synthetic values. Only listed parameters are accepted; arbitrary dates, custom sorting, and duplicate query parameters are rejected. Rows are sorted by their full JSON representation using locale en. The dataset may change between pages; it is not a snapshot. The required scope is dashboard:retail. A supplied X-API-Key takes precedence over the portal session. Authorization is checked before every cache hit.","security":[{"ApiKey":[]},{"PortalSession":[]}],"parameters":[{"name":"period","in":"query","required":false,"description":"Nominal period. Retail uses 4/12/26/52 Weeks; series are aligned to Saturday.","schema":{"type":"string","enum":["28 days","84 days","182 days","365 days"],"default":"365 days"},"example":"365 days"},{"name":"page","in":"query","required":false,"description":"Page per tile; a page past the end returns empty data, not 404.","schema":{"type":"integer","minimum":1,"maximum":100,"default":1},"example":1},{"name":"page_size","in":"query","required":false,"description":"Up to 100 rows per tile, not per response.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"example":50},{"name":"spins_all_iq.geography_region_filter","in":"query","required":false,"description":"Geography; defaults to TOTAL US - MULO. The - MULO suffix is removed before equality comparison. See /retail/filters for options. Single query value; do not repeat the parameter.","schema":{"type":"string","minLength":1,"maxLength":128,"x-max-comma-separated-items":10,"x-normalization":"trim"},"example":"TOTAL US - MULO"},{"name":"spins_all_iq.geography_type","in":"query","required":false,"description":"Geography type matched by equality. Defaults to US Total when no explicit region is provided; when only a region is supplied, no default type is applied. Single query value; do not repeat the parameter.","schema":{"type":"string","minLength":1,"maxLength":128,"x-max-comma-separated-items":10,"x-normalization":"trim"},"example":"US Total"},{"name":"spins_all_iq.labeled_organic","in":"query","required":false,"description":"Growing methods. The accepted combined order is CONVENTIONAL,ORGANIC; this combination is the default. Single query value; do not repeat the parameter.","schema":{"type":"string","enum":["CONVENTIONAL","ORGANIC","CONVENTIONAL,ORGANIC"]},"example":"CONVENTIONAL,ORGANIC"},{"name":"spins_all_iq.base_size_filter","in":"query","required":false,"description":"Up to ten comma-separated sizes; the adapter trims values and removes empty entries. Single query value; do not repeat the parameter.","schema":{"type":"string","minLength":1,"maxLength":128,"x-max-comma-separated-items":10,"x-normalization":"trim"},"example":"6 oz"},{"name":"spins_all_iq.measure_filter","in":"query","required":false,"description":"Selected metric; defaults to LB. Units is estimated; shares and YoY retain the dictionary's caveats. Single query value; do not repeat the parameter.","schema":{"type":"string","enum":["LB","Dollars","Units"]},"example":"LB"},{"name":"spins_all_iq.fresh_frozen","in":"query","required":false,"description":"Affects size comparisons and weekly series; does not remove the separate Fresh/Frozen KPIs. Single query value; do not repeat the parameter.","schema":{"type":"string","enum":["Fresh","Frozen"]},"example":"Fresh"}],"x-cost":5,"x-dashboard":"retail","responses":{"200":{"description":"Page of tiles; see the dictionary for specific fields and calculations.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetailDashboard"},"examples":{"adapter_shape":{"summary":"Adapter structure · fictional values, not measurements","value":{"dashboard":"retail","filters":{"spins_all_iq.measure_filter":"LB","spins_all_iq.labeled_organic":"CONVENTIONAL,ORGANIC","spins_all_iq.current_date_range":"52 Weeks","spins_all_iq.geography_region_filter":"TOTAL US - MULO","spins_all_iq.geography_type":"US Total"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"6287","title":"Total LB (Fresh)","data":[{"spins_all_iq.dynamic_measure_fresh_label":"Total LB (Fresh)","spins_all_iq.dynamic_measure_filter_fresh":100}],"total":1,"has_more":false},{"id":"6289","title":"Total LB (Frozen)","data":[{"spins_all_iq.dynamic_measure_frozen_label":"Total LB (Frozen)","spins_all_iq.dynamic_measure_filter_frozen":100}],"total":1,"has_more":false},{"id":"6292","title":"% of Total LB (Fresh)","data":[{"spins_all_iq.dynamic_measure_fresh_label_perc":"% of Total LB (Fresh)","spins_all_iq.dynamic_measure_filter_fresh_perc":25}],"total":1,"has_more":false},{"id":"6293","title":"LB % Change YoY (Fresh)","data":[{"spins_all_iq.dynamic_measure_fresh_label_yoy":"LB % Change YoY (Fresh)","spins_all_iq.dynamic_measure_filter_fresh_yoy":25}],"total":1,"has_more":false},{"id":"6294","title":"LB % Change YoY (Frozen)","data":[{"spins_all_iq.dynamic_measure_frozen_label_yoy":"LB % Change YoY (Frozen)","spins_all_iq.dynamic_measure_filter_frozen_yoy":25}],"total":1,"has_more":false},{"id":"6295","title":"% of Total LB (Frozen)","data":[{"spins_all_iq.dynamic_measure_frozen_label_perc":"% of Total LB (Frozen)","spins_all_iq.dynamic_measure_filter_frozen_perc":25}],"total":1,"has_more":false},{"id":"6298","title":"Product Size Comparison","data":[{"spins_all_iq.base_size_filter":"6 oz","spins_all_iq.dynamic_measure_filter":100,"spins_all_iq.volume_lbs":100,"spins_all_iq.total_dollars":250,"spins_all_iq.units":16.67,"spins_all_iq.price_usd_lb":2.5}],"total":1,"has_more":false},{"id":"6299","title":"Pricing Trend $/lb","data":[{"spins_all_iq.price_usd_lb_prior":2,"spins_all_iq.price_usd_lb_current":2.5,"spins_all_iq.week_ending":"2026-01-03"}],"total":1,"has_more":false},{"id":"6300","title":"Untitled","data":[{"spins_all_iq.max_week_start":"2026-01-03","spins_all_iq.min_week_start":"2025-01-04"}],"total":1,"has_more":false},{"id":"6302","title":"Total Trend","data":[{"spins_all_iq.week_ending":"2026-01-03","spins_all_iq.dynamic_measure_filter_prior":80,"spins_all_iq.dynamic_measure_filter_updated":100}],"total":1,"has_more":false}],"page":1,"page_size":50}},"decimal_precision":{"summary":"Decimal measures serialized as strings by the SDK · fictional example","value":{"dashboard":"retail","filters":{"spins_all_iq.measure_filter":"LB","spins_all_iq.labeled_organic":"CONVENTIONAL,ORGANIC","spins_all_iq.current_date_range":"52 Weeks","spins_all_iq.geography_region_filter":"TOTAL US - MULO","spins_all_iq.geography_type":"US Total"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"6287","title":"Total LB (Fresh)","data":[{"spins_all_iq.dynamic_measure_fresh_label":"Total LB (Fresh)","spins_all_iq.dynamic_measure_filter_fresh":"100"}],"total":1,"has_more":false},{"id":"6289","title":"Total LB (Frozen)","data":[{"spins_all_iq.dynamic_measure_frozen_label":"Total LB (Frozen)","spins_all_iq.dynamic_measure_filter_frozen":"100"}],"total":1,"has_more":false},{"id":"6292","title":"% of Total LB (Fresh)","data":[{"spins_all_iq.dynamic_measure_fresh_label_perc":"% of Total LB (Fresh)","spins_all_iq.dynamic_measure_filter_fresh_perc":"25"}],"total":1,"has_more":false},{"id":"6293","title":"LB % Change YoY (Fresh)","data":[{"spins_all_iq.dynamic_measure_fresh_label_yoy":"LB % Change YoY (Fresh)","spins_all_iq.dynamic_measure_filter_fresh_yoy":"25"}],"total":1,"has_more":false},{"id":"6294","title":"LB % Change YoY (Frozen)","data":[{"spins_all_iq.dynamic_measure_frozen_label_yoy":"LB % Change YoY (Frozen)","spins_all_iq.dynamic_measure_filter_frozen_yoy":"25"}],"total":1,"has_more":false},{"id":"6295","title":"% of Total LB (Frozen)","data":[{"spins_all_iq.dynamic_measure_frozen_label_perc":"% of Total LB (Frozen)","spins_all_iq.dynamic_measure_filter_frozen_perc":"25"}],"total":1,"has_more":false},{"id":"6298","title":"Product Size Comparison","data":[{"spins_all_iq.base_size_filter":"6 oz","spins_all_iq.dynamic_measure_filter":"100","spins_all_iq.volume_lbs":"100","spins_all_iq.total_dollars":"250","spins_all_iq.units":"16.67","spins_all_iq.price_usd_lb":"2.5"}],"total":1,"has_more":false},{"id":"6299","title":"Pricing Trend $/lb","data":[{"spins_all_iq.price_usd_lb_prior":"2","spins_all_iq.price_usd_lb_current":"2.5","spins_all_iq.week_ending":"2026-01-03"}],"total":1,"has_more":false},{"id":"6300","title":"Untitled","data":[{"spins_all_iq.max_week_start":"2026-01-03","spins_all_iq.min_week_start":"2025-01-04"}],"total":1,"has_more":false},{"id":"6302","title":"Total Trend","data":[{"spins_all_iq.week_ending":"2026-01-03","spins_all_iq.dynamic_measure_filter_prior":"80","spins_all_iq.dynamic_measure_filter_updated":"100"}],"total":1,"has_more":false}],"page":1,"page_size":50}},"demo":{"summary":"Current demo mode response","value":{"dashboard":"retail","filters":{"period":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","demo":true,"tiles":[{"id":"example","title":"Synthetic local example (not industry data)","data":[{"date":"2026-01-01","value":100}],"total":1,"has_more":false}],"page":1,"page_size":50}},"beyond_last_page":{"summary":"Page past the end · synthetic example","value":{"dashboard":"retail","filters":{"spins_all_iq.measure_filter":"LB","spins_all_iq.labeled_organic":"CONVENTIONAL,ORGANIC","spins_all_iq.current_date_range":"52 Weeks","spins_all_iq.geography_region_filter":"TOTAL US - MULO","spins_all_iq.geography_type":"US Total"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"6287","title":"Total LB (Fresh)","data":[],"total":1,"has_more":false},{"id":"6289","title":"Total LB (Frozen)","data":[],"total":1,"has_more":false},{"id":"6292","title":"% of Total LB (Fresh)","data":[],"total":1,"has_more":false},{"id":"6293","title":"LB % Change YoY (Fresh)","data":[],"total":1,"has_more":false},{"id":"6294","title":"LB % Change YoY (Frozen)","data":[],"total":1,"has_more":false},{"id":"6295","title":"% of Total LB (Frozen)","data":[],"total":1,"has_more":false},{"id":"6298","title":"Product Size Comparison","data":[],"total":1,"has_more":false},{"id":"6299","title":"Pricing Trend $/lb","data":[],"total":1,"has_more":false},{"id":"6300","title":"Untitled","data":[],"total":1,"has_more":false},{"id":"6302","title":"Total Trend","data":[],"total":1,"has_more":false}],"page":100,"page_size":50}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.\n\nCredential submitted in a URL parameter. Use the X-API-Key header; never send secrets in URLs.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"credentials_in_query":{"summary":"credentials_in_query","value":{"error":{"code":"credentials_in_query","message":"credentials_in_query","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Attempt to reactivate a revoked key. Issue a new key; revocation is permanent.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_revoked":{"summary":"key_revoked","value":{"error":{"code":"key_revoked","message":"key_revoked","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nUser or organization concurrency exhausted. Honor Retry-After and reduce concurrent requests; the budget may already have been consumed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"concurrency_limit":{"summary":"concurrency_limit","value":{"error":{"code":"concurrency_limit","message":"concurrency_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.\n\nShared cache/lock unavailable, including writes after querying the source. Retry with bounded backoff; there is no cache bypass.\n\nBuild limit reached or the wait of up to 10 seconds for an in-progress cache miss expired. Reduce concurrency and retry with bounded backoff.\n\nThe source query failed or exceeded its limits. Use bounded backoff; report the request ID if the issue persists.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"cache_unavailable":{"summary":"cache_unavailable","value":{"error":{"code":"cache_unavailable","message":"cache_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_busy":{"summary":"source_busy","value":{"error":{"code":"source_busy","message":"source_busy","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_unavailable":{"summary":"source_unavailable","value":{"error":{"code":"source_unavailable","message":"source_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/v1/dashboards/retail/filters":{"get":{"operationId":"getRetailFilters","tags":["Retail SPINS"],"summary":"List filters for Retail SPINS","description":"No query parameters; any parameter is rejected. Returns only supported dimensions. In demo mode, even Retail returns only period; the BigQuery source provides additional Retail options. An unknown dynamic geography/size value may return an empty result; list membership is not validated. The required scope is dashboard:retail. A supplied X-API-Key takes precedence over the portal session.","security":[{"ApiKey":[]},{"PortalSession":[]}],"x-cost":1,"x-dashboard":"retail","responses":{"200":{"description":"Filter names and values. Illustrative example, not a real data query.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetailFilterResponse"},"examples":{"filters":{"summary":"filters","value":{"dashboard":"retail","filters":[{"name":"Period","dimension":"period","values":[{"value":"28 days","label":"28 days"},{"value":"84 days","label":"84 days"},{"value":"182 days","label":"182 days"},{"value":"365 days","label":"365 days"}]},{"name":"Geography","dimension":"spins_all_iq.geography_region_filter","values":[{"value":"TOTAL US","label":"TOTAL US"}]}]}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.\n\nCredential submitted in a URL parameter. Use the X-API-Key header; never send secrets in URLs.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"credentials_in_query":{"summary":"credentials_in_query","value":{"error":{"code":"credentials_in_query","message":"credentials_in_query","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Attempt to reactivate a revoked key. Issue a new key; revocation is permanent.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_revoked":{"summary":"key_revoked","value":{"error":{"code":"key_revoked","message":"key_revoked","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nUser or organization concurrency exhausted. Honor Retry-After and reduce concurrent requests; the budget may already have been consumed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"concurrency_limit":{"summary":"concurrency_limit","value":{"error":{"code":"concurrency_limit","message":"concurrency_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.\n\nShared cache/lock unavailable, including writes after querying the source. Retry with bounded backoff; there is no cache bypass.\n\nBuild limit reached or the wait of up to 10 seconds for an in-progress cache miss expired. Reduce concurrency and retry with bounded backoff.\n\nThe source query failed or exceeded its limits. Use bounded backoff; report the request ID if the issue persists.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"cache_unavailable":{"summary":"cache_unavailable","value":{"error":{"code":"cache_unavailable","message":"cache_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_busy":{"summary":"source_busy","value":{"error":{"code":"source_busy","message":"source_busy","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_unavailable":{"summary":"source_unavailable","value":{"error":{"code":"source_unavailable","message":"source_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/v1/dashboards/imports":{"get":{"operationId":"getImportsDashboard","tags":["USDA Imports"],"summary":"Get USDA Imports","description":"Pre-aggregated import volumes by country, HS code, and berry category. Accepts only 365 days. This value represents the pre-aggregated current period, not an exact 365-day rolling window. DAY(week_ending)=1 identifies current rows; other rows provide pounds_ya for comparison. Percentage changes are ratios: 0.25 = 25%, unlike Retail's percentage fields. Measures may be numbers or decimal strings depending on the underlying BigQuery type (the SDK preserves NUMERIC/BIGNUMERIC precision). The actual source schema still requires validation; examples use synthetic values. Only listed parameters are accepted; arbitrary dates, custom sorting, and duplicate query parameters are rejected. Rows are sorted by their full JSON representation using locale en. The dataset may change between pages; it is not a snapshot. The required scope is dashboard:imports. A supplied X-API-Key takes precedence over the portal session. Authorization is checked before every cache hit.","security":[{"ApiKey":[]},{"PortalSession":[]}],"parameters":[{"name":"period","in":"query","required":false,"description":"Pre-aggregated current period; other values are rejected. This is not a rolling window.","schema":{"type":"string","enum":["365 days"],"default":"365 days"},"example":"365 days"},{"name":"page","in":"query","required":false,"description":"Page per tile; a page past the end returns empty data, not 404.","schema":{"type":"integer","minimum":1,"maximum":100,"default":1},"example":1},{"name":"page_size","in":"query","required":false,"description":"Up to 100 rows per tile, not per response.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"example":50}],"x-cost":5,"x-dashboard":"imports","responses":{"200":{"description":"Page of tiles; see the dictionary for specific fields and calculations.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportsDashboard"},"examples":{"adapter_shape":{"summary":"Adapter structure · fictional values, not measurements","value":{"dashboard":"imports","filters":{"gats_census_trade.current_date_range":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"1258","title":"Berry Imports by Country","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_pounds_current":{"gats_census_trade.hs10_code_type":{"Fresh Conventional Blueberries":10,"Fresh Organic Blueberries":10,"Fresh Wild Blueberries":10,"Frozen Conventional Blueberries":10,"Frozen Organic Blueberries":10,"Frozen Wild Blueberries":10,"Dried Highbush Blueberries":10,"Dried Wild Blueberries":10}}}],"total":1,"has_more":false},{"id":"1259","title":"Map by Source Country","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_quantity_1":100}],"total":1,"has_more":false},{"id":"1261","title":"Import Volume by Berry","data":[{"gats_census_trade.hs10_code_":"0810400024","gats_census_trade.hs10_code_type":"Fresh Wild Blueberries","gats_census_trade.total_pounds_prior":80,"gats_census_trade.total_pounds_change":0.25,"gats_census_trade.total_pounds_current":100}],"total":1,"has_more":false},{"id":"1262","title":"Monthly Imports by Berry Type","data":[{"gats_census_trade.date_in_period_month":"2026-01","gats_census_trade.total_pounds_current":{"gats_census_trade.hs10_code_type":{"Fresh Conventional Blueberries":10,"Fresh Organic Blueberries":10,"Fresh Wild Blueberries":10,"Frozen Conventional Blueberries":10,"Frozen Organic Blueberries":10,"Frozen Wild Blueberries":10,"Dried Highbush Blueberries":10,"Dried Wild Blueberries":10}}}],"total":1,"has_more":false},{"id":"1263","title":"Imports by Berry Type","data":[{"gats_census_trade.date_in_period_month":"2026-01","gats_census_trade.total_pounds_current":{"gats_census_trade.hs10_code_":{"0810400024":{"gats_census_trade.hs10_code_type":{"Fresh Wild Blueberries":10}},"0810400026":{"gats_census_trade.hs10_code_type":{"Fresh Organic Blueberries":10}},"0810400029":{"gats_census_trade.hs10_code_type":{"Fresh Conventional Blueberries":10}},"0811902024":{"gats_census_trade.hs10_code_type":{"Frozen Wild Blueberries":10}},"0811902030":{"gats_census_trade.hs10_code_type":{"Frozen Organic Blueberries":10}},"0811902040":{"gats_census_trade.hs10_code_type":{"Frozen Conventional Blueberries":10}},"0813402010":{"gats_census_trade.hs10_code_type":{"Dried Wild Blueberries":10}},"0813402020":{"gats_census_trade.hs10_code_type":{"Dried Highbush Blueberries":10}}}}}],"total":1,"has_more":false},{"id":"1265","title":"Untitled","data":[{"gats_census_trade.max_week_start":"2026-01-01"}],"total":1,"has_more":false}],"page":1,"page_size":50}},"decimal_precision":{"summary":"Decimal measures serialized as strings by the SDK · fictional example","value":{"dashboard":"imports","filters":{"gats_census_trade.current_date_range":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"1258","title":"Berry Imports by Country","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_pounds_current":{"gats_census_trade.hs10_code_type":{"Fresh Conventional Blueberries":"10","Fresh Organic Blueberries":"10","Fresh Wild Blueberries":"10","Frozen Conventional Blueberries":"10","Frozen Organic Blueberries":"10","Frozen Wild Blueberries":"10","Dried Highbush Blueberries":"10","Dried Wild Blueberries":"10"}}}],"total":1,"has_more":false},{"id":"1259","title":"Map by Source Country","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_quantity_1":"100"}],"total":1,"has_more":false},{"id":"1261","title":"Import Volume by Berry","data":[{"gats_census_trade.hs10_code_":"0810400024","gats_census_trade.hs10_code_type":"Fresh Wild Blueberries","gats_census_trade.total_pounds_prior":"80","gats_census_trade.total_pounds_change":"0.25","gats_census_trade.total_pounds_current":"100"}],"total":1,"has_more":false},{"id":"1262","title":"Monthly Imports by Berry Type","data":[{"gats_census_trade.date_in_period_month":"2026-01","gats_census_trade.total_pounds_current":{"gats_census_trade.hs10_code_type":{"Fresh Conventional Blueberries":"10","Fresh Organic Blueberries":"10","Fresh Wild Blueberries":"10","Frozen Conventional Blueberries":"10","Frozen Organic Blueberries":"10","Frozen Wild Blueberries":"10","Dried Highbush Blueberries":"10","Dried Wild Blueberries":"10"}}}],"total":1,"has_more":false},{"id":"1263","title":"Imports by Berry Type","data":[{"gats_census_trade.date_in_period_month":"2026-01","gats_census_trade.total_pounds_current":{"gats_census_trade.hs10_code_":{"0810400024":{"gats_census_trade.hs10_code_type":{"Fresh Wild Blueberries":"10"}},"0810400026":{"gats_census_trade.hs10_code_type":{"Fresh Organic Blueberries":"10"}},"0810400029":{"gats_census_trade.hs10_code_type":{"Fresh Conventional Blueberries":"10"}},"0811902024":{"gats_census_trade.hs10_code_type":{"Frozen Wild Blueberries":"10"}},"0811902030":{"gats_census_trade.hs10_code_type":{"Frozen Organic Blueberries":"10"}},"0811902040":{"gats_census_trade.hs10_code_type":{"Frozen Conventional Blueberries":"10"}},"0813402010":{"gats_census_trade.hs10_code_type":{"Dried Wild Blueberries":"10"}},"0813402020":{"gats_census_trade.hs10_code_type":{"Dried Highbush Blueberries":"10"}}}}}],"total":1,"has_more":false},{"id":"1265","title":"Untitled","data":[{"gats_census_trade.max_week_start":"2026-01-01"}],"total":1,"has_more":false}],"page":1,"page_size":50}},"demo":{"summary":"Current demo mode response","value":{"dashboard":"imports","filters":{"period":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","demo":true,"tiles":[{"id":"example","title":"Synthetic local example (not industry data)","data":[{"date":"2026-01-01","value":100}],"total":1,"has_more":false}],"page":1,"page_size":50}},"beyond_last_page":{"summary":"Page past the end · synthetic example","value":{"dashboard":"imports","filters":{"gats_census_trade.current_date_range":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"1258","title":"Berry Imports by Country","data":[],"total":1,"has_more":false},{"id":"1259","title":"Map by Source Country","data":[],"total":1,"has_more":false},{"id":"1261","title":"Import Volume by Berry","data":[],"total":1,"has_more":false},{"id":"1262","title":"Monthly Imports by Berry Type","data":[],"total":1,"has_more":false},{"id":"1263","title":"Imports by Berry Type","data":[],"total":1,"has_more":false},{"id":"1265","title":"Untitled","data":[],"total":1,"has_more":false}],"page":100,"page_size":50}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.\n\nCredential submitted in a URL parameter. Use the X-API-Key header; never send secrets in URLs.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"credentials_in_query":{"summary":"credentials_in_query","value":{"error":{"code":"credentials_in_query","message":"credentials_in_query","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Attempt to reactivate a revoked key. Issue a new key; revocation is permanent.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_revoked":{"summary":"key_revoked","value":{"error":{"code":"key_revoked","message":"key_revoked","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nUser or organization concurrency exhausted. Honor Retry-After and reduce concurrent requests; the budget may already have been consumed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"concurrency_limit":{"summary":"concurrency_limit","value":{"error":{"code":"concurrency_limit","message":"concurrency_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.\n\nShared cache/lock unavailable, including writes after querying the source. Retry with bounded backoff; there is no cache bypass.\n\nBuild limit reached or the wait of up to 10 seconds for an in-progress cache miss expired. Reduce concurrency and retry with bounded backoff.\n\nThe source query failed or exceeded its limits. Use bounded backoff; report the request ID if the issue persists.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"cache_unavailable":{"summary":"cache_unavailable","value":{"error":{"code":"cache_unavailable","message":"cache_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_busy":{"summary":"source_busy","value":{"error":{"code":"source_busy","message":"source_busy","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_unavailable":{"summary":"source_unavailable","value":{"error":{"code":"source_unavailable","message":"source_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/v1/dashboards/imports/filters":{"get":{"operationId":"getImportsFilters","tags":["USDA Imports"],"summary":"List filters for USDA Imports","description":"No query parameters; any parameter is rejected. Returns only supported dimensions. In demo mode, even Retail returns only period; the BigQuery source provides additional Retail options. An unknown dynamic geography/size value may return an empty result; list membership is not validated. The required scope is dashboard:imports. A supplied X-API-Key takes precedence over the portal session.","security":[{"ApiKey":[]},{"PortalSession":[]}],"x-cost":1,"x-dashboard":"imports","responses":{"200":{"description":"Filter names and values. Illustrative example, not a real data query.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportsFilterResponse"},"examples":{"filters":{"summary":"filters","value":{"dashboard":"imports","filters":[{"name":"Period","dimension":"period","values":[{"value":"365 days","label":"365 days"}]}]}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.\n\nCredential submitted in a URL parameter. Use the X-API-Key header; never send secrets in URLs.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"credentials_in_query":{"summary":"credentials_in_query","value":{"error":{"code":"credentials_in_query","message":"credentials_in_query","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Attempt to reactivate a revoked key. Issue a new key; revocation is permanent.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_revoked":{"summary":"key_revoked","value":{"error":{"code":"key_revoked","message":"key_revoked","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nUser or organization concurrency exhausted. Honor Retry-After and reduce concurrent requests; the budget may already have been consumed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"concurrency_limit":{"summary":"concurrency_limit","value":{"error":{"code":"concurrency_limit","message":"concurrency_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.\n\nShared cache/lock unavailable, including writes after querying the source. Retry with bounded backoff; there is no cache bypass.\n\nBuild limit reached or the wait of up to 10 seconds for an in-progress cache miss expired. Reduce concurrency and retry with bounded backoff.\n\nThe source query failed or exceeded its limits. Use bounded backoff; report the request ID if the issue persists.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"cache_unavailable":{"summary":"cache_unavailable","value":{"error":{"code":"cache_unavailable","message":"cache_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_busy":{"summary":"source_busy","value":{"error":{"code":"source_busy","message":"source_busy","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_unavailable":{"summary":"source_unavailable","value":{"error":{"code":"source_unavailable","message":"source_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/v1/dashboards/exports":{"get":{"operationId":"getExportsDashboard","tags":["USDA FAS Exports"],"summary":"Get USDA FAS Exports","description":"Exports (flow_type Export) by country, month, and berry category. Nominal window aligned to Saturday from CURRENT_DATE UTC; SQL does not exclude potential future source dates. The titles “avg”, “Top”, and “Untitled” are legacy labels: see the documented formula; do not infer an average or top N from the title. Changes are ratios: 0.25 = +25%. Measures may be numbers or decimal strings depending on the underlying BigQuery type (the SDK preserves NUMERIC/BIGNUMERIC precision). The actual source schema still requires validation; examples use synthetic values. Only listed parameters are accepted; arbitrary dates, custom sorting, and duplicate query parameters are rejected. Rows are sorted by their full JSON representation using locale en. The dataset may change between pages; it is not a snapshot. The required scope is dashboard:exports. A supplied X-API-Key takes precedence over the portal session. Authorization is checked before every cache hit.","security":[{"ApiKey":[]},{"PortalSession":[]}],"parameters":[{"name":"period","in":"query","required":false,"description":"Nominal period. Retail uses 4/12/26/52 Weeks; series are aligned to Saturday.","schema":{"type":"string","enum":["28 days","84 days","182 days","365 days"],"default":"365 days"},"example":"365 days"},{"name":"page","in":"query","required":false,"description":"Page per tile; a page past the end returns empty data, not 404.","schema":{"type":"integer","minimum":1,"maximum":100,"default":1},"example":1},{"name":"page_size","in":"query","required":false,"description":"Up to 100 rows per tile, not per response.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"example":50}],"x-cost":5,"x-dashboard":"exports","responses":{"200":{"description":"Page of tiles; see the dictionary for specific fields and calculations.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportsDashboard"},"examples":{"adapter_shape":{"summary":"Adapter structure · fictional values, not measurements","value":{"dashboard":"exports","filters":{"gats_census_trade.current_date_range":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"1301","title":"Blueberry Exports by Time","data":[{"gats_census_trade.reporting_month":"2026-01","gats_census_trade.total_pounds_current":{"gats_census_trade.hs10_code_type":{"Fresh Conventional Blueberries":10,"Fresh Organic Blueberries":10,"Fresh Wild Blueberries":10,"Frozen Conventional Blueberries":10,"Frozen Organic Blueberries":10,"Frozen Wild Blueberries":10,"Dried Highbush Blueberries":10,"Dried Wild Blueberries":10}}}],"total":1,"has_more":false},{"id":"1302","title":"Exports by Country","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_quantity_1":100}],"total":1,"has_more":false},{"id":"1303","title":"Exports by Month (avg)","data":[{"gats_census_trade.reporting_month":"2026-01","gats_census_trade.total_quantity_1":100,"gats_census_trade.total_quantity_1_ya":80}],"total":1,"has_more":false},{"id":"1304","title":"Untitled","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_quantity_1":100}],"total":1,"has_more":false},{"id":"1305","title":"Top Export Countries","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_pounds_current":100,"gats_census_trade.total_pounds_prior":80,"gats_census_trade.total_pounds_change":0.25,"gats_census_trade.total_dollars_current":250,"gats_census_trade.total_dollars_prior":200,"gats_census_trade.total_dollars_change":0.25}],"total":1,"has_more":false}],"page":1,"page_size":50}},"decimal_precision":{"summary":"Decimal measures serialized as strings by the SDK · fictional example","value":{"dashboard":"exports","filters":{"gats_census_trade.current_date_range":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"1301","title":"Blueberry Exports by Time","data":[{"gats_census_trade.reporting_month":"2026-01","gats_census_trade.total_pounds_current":{"gats_census_trade.hs10_code_type":{"Fresh Conventional Blueberries":"10","Fresh Organic Blueberries":"10","Fresh Wild Blueberries":"10","Frozen Conventional Blueberries":"10","Frozen Organic Blueberries":"10","Frozen Wild Blueberries":"10","Dried Highbush Blueberries":"10","Dried Wild Blueberries":"10"}}}],"total":1,"has_more":false},{"id":"1302","title":"Exports by Country","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_quantity_1":"100"}],"total":1,"has_more":false},{"id":"1303","title":"Exports by Month (avg)","data":[{"gats_census_trade.reporting_month":"2026-01","gats_census_trade.total_quantity_1":"100","gats_census_trade.total_quantity_1_ya":"80"}],"total":1,"has_more":false},{"id":"1304","title":"Untitled","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_quantity_1":"100"}],"total":1,"has_more":false},{"id":"1305","title":"Top Export Countries","data":[{"gats_census_trade.country_name":"Example country","gats_census_trade.total_pounds_current":"100","gats_census_trade.total_pounds_prior":"80","gats_census_trade.total_pounds_change":"0.25","gats_census_trade.total_dollars_current":"250","gats_census_trade.total_dollars_prior":"200","gats_census_trade.total_dollars_change":"0.25"}],"total":1,"has_more":false}],"page":1,"page_size":50}},"demo":{"summary":"Current demo mode response","value":{"dashboard":"exports","filters":{"period":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","demo":true,"tiles":[{"id":"example","title":"Synthetic local example (not industry data)","data":[{"date":"2026-01-01","value":100}],"total":1,"has_more":false}],"page":1,"page_size":50}},"beyond_last_page":{"summary":"Page past the end · synthetic example","value":{"dashboard":"exports","filters":{"gats_census_trade.current_date_range":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"1301","title":"Blueberry Exports by Time","data":[],"total":1,"has_more":false},{"id":"1302","title":"Exports by Country","data":[],"total":1,"has_more":false},{"id":"1303","title":"Exports by Month (avg)","data":[],"total":1,"has_more":false},{"id":"1304","title":"Untitled","data":[],"total":1,"has_more":false},{"id":"1305","title":"Top Export Countries","data":[],"total":1,"has_more":false}],"page":100,"page_size":50}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.\n\nCredential submitted in a URL parameter. Use the X-API-Key header; never send secrets in URLs.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"credentials_in_query":{"summary":"credentials_in_query","value":{"error":{"code":"credentials_in_query","message":"credentials_in_query","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Attempt to reactivate a revoked key. Issue a new key; revocation is permanent.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_revoked":{"summary":"key_revoked","value":{"error":{"code":"key_revoked","message":"key_revoked","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nUser or organization concurrency exhausted. Honor Retry-After and reduce concurrent requests; the budget may already have been consumed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"concurrency_limit":{"summary":"concurrency_limit","value":{"error":{"code":"concurrency_limit","message":"concurrency_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.\n\nShared cache/lock unavailable, including writes after querying the source. Retry with bounded backoff; there is no cache bypass.\n\nBuild limit reached or the wait of up to 10 seconds for an in-progress cache miss expired. Reduce concurrency and retry with bounded backoff.\n\nThe source query failed or exceeded its limits. Use bounded backoff; report the request ID if the issue persists.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"cache_unavailable":{"summary":"cache_unavailable","value":{"error":{"code":"cache_unavailable","message":"cache_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_busy":{"summary":"source_busy","value":{"error":{"code":"source_busy","message":"source_busy","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_unavailable":{"summary":"source_unavailable","value":{"error":{"code":"source_unavailable","message":"source_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/v1/dashboards/exports/filters":{"get":{"operationId":"getExportsFilters","tags":["USDA FAS Exports"],"summary":"List filters for USDA FAS Exports","description":"No query parameters; any parameter is rejected. Returns only supported dimensions. In demo mode, even Retail returns only period; the BigQuery source provides additional Retail options. An unknown dynamic geography/size value may return an empty result; list membership is not validated. The required scope is dashboard:exports. A supplied X-API-Key takes precedence over the portal session.","security":[{"ApiKey":[]},{"PortalSession":[]}],"x-cost":1,"x-dashboard":"exports","responses":{"200":{"description":"Filter names and values. Illustrative example, not a real data query.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportsFilterResponse"},"examples":{"filters":{"summary":"filters","value":{"dashboard":"exports","filters":[{"name":"Period","dimension":"period","values":[{"value":"28 days","label":"28 days"},{"value":"84 days","label":"84 days"},{"value":"182 days","label":"182 days"},{"value":"365 days","label":"365 days"}]}]}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.\n\nCredential submitted in a URL parameter. Use the X-API-Key header; never send secrets in URLs.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"credentials_in_query":{"summary":"credentials_in_query","value":{"error":{"code":"credentials_in_query","message":"credentials_in_query","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Attempt to reactivate a revoked key. Issue a new key; revocation is permanent.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_revoked":{"summary":"key_revoked","value":{"error":{"code":"key_revoked","message":"key_revoked","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nUser or organization concurrency exhausted. Honor Retry-After and reduce concurrent requests; the budget may already have been consumed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"concurrency_limit":{"summary":"concurrency_limit","value":{"error":{"code":"concurrency_limit","message":"concurrency_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.\n\nShared cache/lock unavailable, including writes after querying the source. Retry with bounded backoff; there is no cache bypass.\n\nBuild limit reached or the wait of up to 10 seconds for an in-progress cache miss expired. Reduce concurrency and retry with bounded backoff.\n\nThe source query failed or exceeded its limits. Use bounded backoff; report the request ID if the issue persists.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"cache_unavailable":{"summary":"cache_unavailable","value":{"error":{"code":"cache_unavailable","message":"cache_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_busy":{"summary":"source_busy","value":{"error":{"code":"source_busy","message":"source_busy","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_unavailable":{"summary":"source_unavailable","value":{"error":{"code":"source_unavailable","message":"source_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/v1/dashboards/usda-ams":{"get":{"operationId":"getUsdaAmsDashboard","tags":["USDA AMS"],"summary":"Get USDA AMS","description":"FOB prices and movement in lb, aggregated by period and origin. Nominal window aligned to Saturday from CURRENT_DATE UTC; SQL has no explicit upper bound. Titles containing YoY return monthly series; the adapter does not calculate the change. USDA Market News returns volumes by origin. This tile contains no news, posts, or Apify collection. Prices are arithmetic means of positive values; they are not weighted by volume. Measures may be numbers or decimal strings depending on the underlying BigQuery type (the SDK preserves NUMERIC/BIGNUMERIC precision). The actual source schema still requires validation; examples use synthetic values. Only listed parameters are accepted; arbitrary dates, custom sorting, and duplicate query parameters are rejected. Rows are sorted by their full JSON representation using locale en. The dataset may change between pages; it is not a snapshot. The required scope is dashboard:usda-ams. A supplied X-API-Key takes precedence over the portal session. Authorization is checked before every cache hit.","security":[{"ApiKey":[]},{"PortalSession":[]}],"parameters":[{"name":"period","in":"query","required":false,"description":"Nominal period. Retail uses 4/12/26/52 Weeks; series are aligned to Saturday.","schema":{"type":"string","enum":["28 days","84 days","182 days","365 days"],"default":"365 days"},"example":"365 days"},{"name":"page","in":"query","required":false,"description":"Page per tile; a page past the end returns empty data, not 404.","schema":{"type":"integer","minimum":1,"maximum":100,"default":1},"example":1},{"name":"page_size","in":"query","required":false,"description":"Up to 100 rows per tile, not per response.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"example":50}],"x-cost":5,"x-dashboard":"usda-ams","responses":{"200":{"description":"Page of tiles; see the dictionary for specific fields and calculations.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsdaAmsDashboard"},"examples":{"adapter_shape":{"summary":"Adapter structure · fictional values, not measurements","value":{"dashboard":"usda-ams","filters":{"usda_region_pricing_movement.data_date":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"8274","title":"Average FOB Price/Lb","data":[{"usda_region_pricing_movement.price":2.5}],"total":1,"has_more":false},{"id":"8275","title":"Date As Of","data":[{"usda_region_pricing_movement.data_date":"2026-01-03"}],"total":1,"has_more":false},{"id":"8276","title":"FOB Change YoY","data":[{"usda_region_pricing_movement.price":2.5,"usda_region_pricing_movement.data_month":"2026-01"}],"total":1,"has_more":false},{"id":"8277","title":"Movement (Lbs) Change YoY","data":[{"usda_region_pricing_movement.data_month":"2026-01","usda_region_pricing_movement.movement_lbs":100}],"total":1,"has_more":false},{"id":"8278","title":"Total Movement Current KPI","data":[{"usda_region_pricing_movement.movement_lbs":100}],"total":1,"has_more":false},{"id":"8279","title":"USDA Market News","data":[{"usda_region_pricing_movement.movement_lbs":100,"usda_region_pricing_movement.pricing_origin":"Example origin"}],"total":1,"has_more":false},{"id":"8280","title":"USDA Movement and Pricing by Week","data":[{"usda_region_pricing_movement.price":2.5,"usda_region_pricing_movement.data_date":"2026-01-03","usda_region_pricing_movement.movement_lbs":100}],"total":1,"has_more":false},{"id":"8281","title":"Weekly Movement by Region","data":[{"usda_region_pricing_movement.data_week":"2025-12-28","usda_region_pricing_movement.movement_lbs":{"usda_region_pricing_movement.pricing_origin":{"Example origin":100}}}],"total":1,"has_more":false}],"page":1,"page_size":50}},"decimal_precision":{"summary":"Decimal measures serialized as strings by the SDK · fictional example","value":{"dashboard":"usda-ams","filters":{"usda_region_pricing_movement.data_date":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"8274","title":"Average FOB Price/Lb","data":[{"usda_region_pricing_movement.price":"2.5"}],"total":1,"has_more":false},{"id":"8275","title":"Date As Of","data":[{"usda_region_pricing_movement.data_date":"2026-01-03"}],"total":1,"has_more":false},{"id":"8276","title":"FOB Change YoY","data":[{"usda_region_pricing_movement.price":"2.5","usda_region_pricing_movement.data_month":"2026-01"}],"total":1,"has_more":false},{"id":"8277","title":"Movement (Lbs) Change YoY","data":[{"usda_region_pricing_movement.data_month":"2026-01","usda_region_pricing_movement.movement_lbs":"100"}],"total":1,"has_more":false},{"id":"8278","title":"Total Movement Current KPI","data":[{"usda_region_pricing_movement.movement_lbs":"100"}],"total":1,"has_more":false},{"id":"8279","title":"USDA Market News","data":[{"usda_region_pricing_movement.movement_lbs":"100","usda_region_pricing_movement.pricing_origin":"Example origin"}],"total":1,"has_more":false},{"id":"8280","title":"USDA Movement and Pricing by Week","data":[{"usda_region_pricing_movement.price":"2.5","usda_region_pricing_movement.data_date":"2026-01-03","usda_region_pricing_movement.movement_lbs":"100"}],"total":1,"has_more":false},{"id":"8281","title":"Weekly Movement by Region","data":[{"usda_region_pricing_movement.data_week":"2025-12-28","usda_region_pricing_movement.movement_lbs":{"usda_region_pricing_movement.pricing_origin":{"Example origin":"100"}}}],"total":1,"has_more":false}],"page":1,"page_size":50}},"demo":{"summary":"Current demo mode response","value":{"dashboard":"usda-ams","filters":{"period":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","demo":true,"tiles":[{"id":"example","title":"Synthetic local example (not industry data)","data":[{"date":"2026-01-01","value":100}],"total":1,"has_more":false}],"page":1,"page_size":50}},"beyond_last_page":{"summary":"Page past the end · synthetic example","value":{"dashboard":"usda-ams","filters":{"usda_region_pricing_movement.data_date":"365 days"},"fetched_at":"2026-11-03T12:00:00.000Z","timezone":"UTC","tiles":[{"id":"8274","title":"Average FOB Price/Lb","data":[],"total":1,"has_more":false},{"id":"8275","title":"Date As Of","data":[],"total":1,"has_more":false},{"id":"8276","title":"FOB Change YoY","data":[],"total":1,"has_more":false},{"id":"8277","title":"Movement (Lbs) Change YoY","data":[],"total":1,"has_more":false},{"id":"8278","title":"Total Movement Current KPI","data":[],"total":1,"has_more":false},{"id":"8279","title":"USDA Market News","data":[],"total":1,"has_more":false},{"id":"8280","title":"USDA Movement and Pricing by Week","data":[],"total":1,"has_more":false},{"id":"8281","title":"Weekly Movement by Region","data":[],"total":1,"has_more":false}],"page":100,"page_size":50}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.\n\nCredential submitted in a URL parameter. Use the X-API-Key header; never send secrets in URLs.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"credentials_in_query":{"summary":"credentials_in_query","value":{"error":{"code":"credentials_in_query","message":"credentials_in_query","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Attempt to reactivate a revoked key. Issue a new key; revocation is permanent.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_revoked":{"summary":"key_revoked","value":{"error":{"code":"key_revoked","message":"key_revoked","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nUser or organization concurrency exhausted. Honor Retry-After and reduce concurrent requests; the budget may already have been consumed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"concurrency_limit":{"summary":"concurrency_limit","value":{"error":{"code":"concurrency_limit","message":"concurrency_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.\n\nShared cache/lock unavailable, including writes after querying the source. Retry with bounded backoff; there is no cache bypass.\n\nBuild limit reached or the wait of up to 10 seconds for an in-progress cache miss expired. Reduce concurrency and retry with bounded backoff.\n\nThe source query failed or exceeded its limits. Use bounded backoff; report the request ID if the issue persists.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"cache_unavailable":{"summary":"cache_unavailable","value":{"error":{"code":"cache_unavailable","message":"cache_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_busy":{"summary":"source_busy","value":{"error":{"code":"source_busy","message":"source_busy","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_unavailable":{"summary":"source_unavailable","value":{"error":{"code":"source_unavailable","message":"source_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/v1/dashboards/usda-ams/filters":{"get":{"operationId":"getUsdaAmsFilters","tags":["USDA AMS"],"summary":"List filters for USDA AMS","description":"No query parameters; any parameter is rejected. Returns only supported dimensions. In demo mode, even Retail returns only period; the BigQuery source provides additional Retail options. An unknown dynamic geography/size value may return an empty result; list membership is not validated. The required scope is dashboard:usda-ams. A supplied X-API-Key takes precedence over the portal session.","security":[{"ApiKey":[]},{"PortalSession":[]}],"x-cost":1,"x-dashboard":"usda-ams","responses":{"200":{"description":"Filter names and values. Illustrative example, not a real data query.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsdaAmsFilterResponse"},"examples":{"filters":{"summary":"filters","value":{"dashboard":"usda-ams","filters":[{"name":"Period","dimension":"period","values":[{"value":"28 days","label":"28 days"},{"value":"84 days","label":"84 days"},{"value":"182 days","label":"182 days"},{"value":"365 days","label":"365 days"}]}]}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.\n\nCredential submitted in a URL parameter. Use the X-API-Key header; never send secrets in URLs.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"credentials_in_query":{"summary":"credentials_in_query","value":{"error":{"code":"credentials_in_query","message":"credentials_in_query","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Attempt to reactivate a revoked key. Issue a new key; revocation is permanent.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_revoked":{"summary":"key_revoked","value":{"error":{"code":"key_revoked","message":"key_revoked","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nUser or organization concurrency exhausted. Honor Retry-After and reduce concurrent requests; the budget may already have been consumed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"concurrency_limit":{"summary":"concurrency_limit","value":{"error":{"code":"concurrency_limit","message":"concurrency_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.\n\nShared cache/lock unavailable, including writes after querying the source. Retry with bounded backoff; there is no cache bypass.\n\nBuild limit reached or the wait of up to 10 seconds for an in-progress cache miss expired. Reduce concurrency and retry with bounded backoff.\n\nThe source query failed or exceeded its limits. Use bounded backoff; report the request ID if the issue persists.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"RateLimit-Limit":{"schema":{"type":"integer","description":"Nominal sustained key budget per minute.","minimum":1},"description":"Cost units, not request counts. Optional on errors: may be present if the budget was admitted before the failure.","example":120},"RateLimit-Remaining":{"schema":{"type":"integer","description":"Lowest remaining balance across key/user/organization/IP budgets.","minimum":0},"description":"Balance after charging the cost. This is not reserved capacity and excludes the IP ingress limit. Optional on errors: may be present if the budget was admitted before the failure.","example":15},"RateLimit-Reset":{"schema":{"type":"integer","description":"Seconds in the maximum sustained window.","minimum":1},"description":"The application returns 60, not a Unix timestamp or an exact countdown for the short window. Optional on errors: may be present if the budget was admitted before the failure.","example":60}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"cache_unavailable":{"summary":"cache_unavailable","value":{"error":{"code":"cache_unavailable","message":"cache_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_busy":{"summary":"source_busy","value":{"error":{"code":"source_busy","message":"source_busy","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"source_unavailable":{"summary":"source_unavailable","value":{"error":{"code":"source_unavailable","message":"source_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/auth/status":{"get":{"tags":["Authentication"],"security":[],"operationId":"getAuthStatus","summary":"Check login availability","description":"Reports the configured identity provider, whether its login flow is enabled, and whether data are synthetic. Availability reflects configuration.","responses":{"200":{"description":"Current authentication configuration.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"provider":{"type":"string","enum":["development","glueup"]},"login_available":{"type":"boolean"},"demo":{"type":"boolean"}},"required":["provider","login_available","demo"]},"examples":{"development":{"summary":"development","value":{"provider":"development","login_available":true,"demo":true}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/auth/login":{"post":{"tags":["Authentication"],"security":[],"operationId":"login","summary":"Sign in to the developer portal","description":"Development login accepts developer@example.test and the configured password. Check GET /auth/status for availability. This release returns 501 when configured for Glue Up. Successful development verification lasts 15 minutes. Save the response cookie for portal requests and use the CSRF token for mutations.","parameters":[{"name":"Origin","in":"header","required":true,"description":"Must match the configured portal origin exactly.","schema":{"type":"string"},"example":"https://di-industry.blueberry.org"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","description":"Account email.","format":"email","maxLength":254},"password":{"type":"string","description":"Account password.","format":"password","minLength":1,"maxLength":256}},"required":["email","password"]},"examples":{"example":{"summary":"example","value":{"email":"developer@example.test","password":"replace-with-configured-password"}}}}}},"responses":{"200":{"description":"Session established.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Set-Cookie":{"schema":{"type":"string"},"description":"Sets the HttpOnly, SameSite=Strict portal_session cookie at Path=/. Secure in production."},"X-Account-Initial":{"schema":{"type":"string"},"description":"Uppercased first character of the account email, percent-encoded.","example":"D"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"scopes":{"type":"array","items":{"type":"string","enum":["dashboard:retail","dashboard:imports","dashboard:exports","dashboard:usda-ams"]}},"verified_until":{"type":"string","description":"ISO 8601 timestamp with time zone.","format":"date-time"},"csrf_token":{"type":"string","description":"Token for portal mutations."}},"required":["scopes","verified_until","csrf_token"]},"examples":{"session":{"summary":"session","value":{"scopes":["dashboard:imports"],"verified_until":"2026-11-03T12:00:00.000Z","csrf_token":"example-csrf-token"}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"Login Origin differs from the configured origin. Use the portal at the origin listed in servers; browsers send Origin automatically.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"origin_forbidden":{"summary":"origin_forbidden","value":{"error":{"code":"origin_forbidden","message":"origin_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"413":{"description":"Body exceeds the 8192-byte limit; HTTP error normalized by the current handler. Reduce the body size. This error's message is Request rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Request rejected","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"415":{"description":"Content-Type not accepted by the parser; HTTP error normalized by the current handler. Use application/json for bodies; omit Content-Type on bodyless DELETE/logout requests.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Request rejected","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"501":{"description":"Glue Up sign-in is disabled for this configuration. Check GET /auth/status. The Glue Up flow and grants await approval.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"glueup_pending_confirmation":{"summary":"glueup_pending_confirmation","value":{"error":{"code":"glueup_pending_confirmation","message":"Glue Up sign-in is unavailable in this environment","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/portal/session":{"get":{"tags":["Account portal"],"security":[{"PortalSession":[]}],"operationId":"getPortalSession","summary":"Resume a portal session","description":"Returns the scopes and verification expiry of the signed-in account. Read the X-CSRF-Token response header to resume authenticated mutations after reloading.","responses":{"200":{"description":"Current session.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"X-CSRF-Token":{"schema":{"type":"string"},"description":"Current session token for portal mutations.","example":"example-csrf-token"},"X-Account-Initial":{"schema":{"type":"string"},"description":"Uppercased first character of the account email, percent-encoded.","example":"D"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"scopes":{"type":"array","items":{"type":"string","enum":["dashboard:retail","dashboard:imports","dashboard:exports","dashboard:usda-ams"]}},"verified_until":{"type":"string","description":"ISO 8601 timestamp with time zone.","format":"date-time"}},"required":["scopes","verified_until"]},"examples":{"session":{"summary":"session","value":{"scopes":["dashboard:imports"],"verified_until":"2026-11-03T12:00:00.000Z"}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/portal/profile":{"get":{"tags":["Account portal"],"security":[{"PortalSession":[]}],"operationId":"getPortalProfile","summary":"Read your profile","description":"Returns the email and display name of the account associated with the portal session.","responses":{"200":{"description":"Current profile.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","description":"Account email.","format":"email"},"display_name":{"type":"string","description":"Display name. An empty string is allowed.","maxLength":80}},"required":["email","display_name"]},"examples":{"profile":{"summary":"profile","value":{"email":"developer@example.test","display_name":"Example Developer"}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}},"patch":{"tags":["Account portal"],"security":[{"PortalSession":[]}],"operationId":"updatePortalProfile","summary":"Update your display name","description":"Trims surrounding whitespace before validating the 80-character limit. An empty string clears the name. Browser requests must use the portal origin, since cross-origin preflight does not allow PATCH.","parameters":[{"name":"Origin","in":"header","required":true,"description":"Must match the configured portal origin exactly.","schema":{"type":"string"},"example":"https://di-industry.blueberry.org"},{"name":"X-CSRF-Token","in":"header","required":true,"description":"Token returned at login or in the X-CSRF-Token response header from GET /portal/session.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"display_name":{"type":"string","description":"Display name. An empty string is allowed.","maxLength":80}},"required":["display_name"]},"examples":{"example":{"summary":"example","value":{"display_name":"Example Developer"}}}}}},"responses":{"200":{"description":"Updated profile.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","description":"Account email.","format":"email"},"display_name":{"type":"string","description":"Display name. An empty string is allowed.","maxLength":80}},"required":["email","display_name"]},"examples":{"profile":{"summary":"profile","value":{"email":"developer@example.test","display_name":"Example Developer"}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"Invalid Origin or CSRF token in a portal mutation. Sign in to the portal again and use the current session's CSRF token.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"csrf_failed":{"summary":"csrf_failed","value":{"error":{"code":"csrf_failed","message":"csrf_failed","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"413":{"description":"Body exceeds the 8192-byte limit; HTTP error normalized by the current handler. Reduce the body size. This error's message is Request rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Request rejected","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"415":{"description":"Content-Type not accepted by the parser; HTTP error normalized by the current handler. Use application/json for bodies; omit Content-Type on bodyless DELETE/logout requests.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Request rejected","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/auth/logout":{"post":{"tags":["Authentication"],"security":[{"PortalSession":[]}],"operationId":"logout","summary":"Sign out of the developer portal","description":"Deletes the current session and clears the session cookie. Send an empty request without Content-Type.","parameters":[{"name":"Origin","in":"header","required":true,"description":"Must match the configured portal origin exactly.","schema":{"type":"string"},"example":"https://di-industry.blueberry.org"},{"name":"X-CSRF-Token","in":"header","required":true,"description":"Token returned at login or in the X-CSRF-Token response header from GET /portal/session.","schema":{"type":"string"}}],"responses":{"200":{"description":"Session ended.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Set-Cookie":{"schema":{"type":"string"},"description":"Clears the portal_session cookie at Path=/."}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"logged_out":{"type":"boolean","const":true}},"required":["logged_out"]},"examples":{"logout":{"summary":"logout","value":{"logged_out":true}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"Invalid Origin or CSRF token in a portal mutation. Sign in to the portal again and use the current session's CSRF token.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"csrf_failed":{"summary":"csrf_failed","value":{"error":{"code":"csrf_failed","message":"csrf_failed","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/portal/keys":{"get":{"tags":["Account portal"],"security":[{"PortalSession":[]}],"operationId":"listPortalKeys","summary":"List your API keys","description":"Returns up to 100 records for the signed-in account, ordered by creation time and then ID, newest first. There is no pagination. Full secrets are only returned on creation or rotation.","responses":{"200":{"description":"Key metadata.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"keys":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","description":"UUID identifier.","format":"uuid"},"name":{"type":"string","description":"Display name."},"prefix":{"type":"string","description":"First 12 characters of the key."},"organization_id":{"type":"string","description":"Issuing organization."},"scopes":{"type":"array","items":{"type":"string","enum":["dashboard:retail","dashboard:imports","dashboard:exports","dashboard:usda-ams"]}},"state":{"type":"string","enum":["active","blocked","revoked"]},"reason":{"type":["string","null"]},"created_at":{"type":"string","description":"ISO 8601 timestamp with time zone.","format":"date-time"},"expires_at":{"type":"string","description":"ISO 8601 timestamp with time zone.","format":"date-time"},"last_used_at":{"type":["string","null"],"description":"ISO 8601 timestamp with time zone.","format":"date-time"}},"required":["id","name","prefix","organization_id","scopes","state","reason","created_at","expires_at","last_used_at"]}}},"required":["keys"]},"examples":{"keys":{"summary":"keys","value":{"keys":[{"id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822","name":"Imports integration","prefix":"bbi_00000000","organization_id":"development","scopes":["dashboard:imports"],"state":"active","reason":null,"created_at":"2026-11-03T12:00:00.000Z","expires_at":"2026-11-04T12:00:00.000Z","last_used_at":null}]}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}},"post":{"tags":["Account portal"],"security":[{"PortalSession":[]}],"operationId":"createPortalKey","summary":"Create an API key","description":"Creates a key for the signed-in account, subject to the active-key limit. Requested scopes must be a subset of account grants. Creation and rotation share a limit of 10 attempts per hour per account. The secret is shown once. After an ambiguous failure, check the key list before retrying.","parameters":[{"name":"Origin","in":"header","required":true,"description":"Must match the configured portal origin exactly.","schema":{"type":"string"},"example":"https://di-industry.blueberry.org"},{"name":"X-CSRF-Token","in":"header","required":true,"description":"Token returned at login or in the X-CSRF-Token response header from GET /portal/session.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","description":"Key name, trimmed before validation.","minLength":1,"maxLength":80},"scopes":{"type":"array","items":{"type":"string","enum":["dashboard:retail","dashboard:imports","dashboard:exports","dashboard:usda-ams"]},"minItems":1,"maxItems":4,"uniqueItems":true},"days":{"type":"integer","description":"Lifetime in days.","minimum":1,"maximum":90,"default":90}},"required":["name","scopes"]},"examples":{"example":{"summary":"example","value":{"name":"Imports integration","scopes":["dashboard:imports"],"days":1}}}}}},"responses":{"201":{"description":"Key created. Store the secret securely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"key":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","description":"UUID identifier.","format":"uuid"},"name":{"type":"string","description":"Display name."},"prefix":{"type":"string","description":"First 12 characters of the key."},"organization_id":{"type":"string","description":"Issuing organization."},"scopes":{"type":"array","items":{"type":"string","enum":["dashboard:retail","dashboard:imports","dashboard:exports","dashboard:usda-ams"]}},"state":{"type":"string","enum":["active","blocked","revoked"]},"reason":{"type":["string","null"]},"created_at":{"type":"string","description":"ISO 8601 timestamp with time zone.","format":"date-time"},"expires_at":{"type":"string","description":"ISO 8601 timestamp with time zone.","format":"date-time"},"last_used_at":{"type":["string","null"],"description":"ISO 8601 timestamp with time zone.","format":"date-time"}},"required":["id","name","prefix","organization_id","scopes","state","reason","created_at","expires_at","last_used_at"]},"secret":{"type":"string","description":"Full API key, displayed once.","pattern":"^bbi_[A-Za-z0-9_-]{43}$"}},"required":["key","secret"]},"examples":{"issued":{"summary":"issued","value":{"key":{"id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822","name":"Imports integration","prefix":"bbi_00000000","organization_id":"development","scopes":["dashboard:imports"],"state":"active","reason":null,"created_at":"2026-11-03T12:00:00.000Z","expires_at":"2026-11-04T12:00:00.000Z","last_used_at":null},"secret":"bbi_0000000000000000000000000000000000000000000"}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.\n\nInvalid Origin or CSRF token in a portal mutation. Sign in to the portal again and use the current session's CSRF token.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"csrf_failed":{"summary":"csrf_failed","value":{"error":{"code":"csrf_failed","message":"csrf_failed","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Maximum number of active keys reached. Revoke a key or rotate an existing one.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"active_key_limit":{"summary":"active_key_limit","value":{"error":{"code":"active_key_limit","message":"active_key_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"413":{"description":"Body exceeds the 8192-byte limit; HTTP error normalized by the current handler. Reduce the body size. This error's message is Request rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Request rejected","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"415":{"description":"Content-Type not accepted by the parser; HTTP error normalized by the current handler. Use application/json for bodies; omit Content-Type on bodyless DELETE/logout requests.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Request rejected","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nShared creation and rotation limit exceeded. Wait for Retry-After before creating or rotating again.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"key_creation_limit":{"summary":"key_creation_limit","value":{"error":{"code":"key_creation_limit","message":"key_creation_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/portal/keys/{id}/rotate":{"post":{"tags":["Account portal"],"security":[{"PortalSession":[]}],"operationId":"rotatePortalKey","summary":"Rotate an API key","description":"Replaces an active, unexpired key owned by the account. The old key is revoked in the same transaction and there is no overlap. Requested scopes must be a subset of account grants. Creation and rotation share a limit of 10 attempts per hour per account. The secret is shown once. After an ambiguous failure, check the key list before retrying.","parameters":[{"name":"id","in":"path","required":true,"description":"Public key ID obtained from the key list.","schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},{"name":"Origin","in":"header","required":true,"description":"Must match the configured portal origin exactly.","schema":{"type":"string"},"example":"https://di-industry.blueberry.org"},{"name":"X-CSRF-Token","in":"header","required":true,"description":"Token returned at login or in the X-CSRF-Token response header from GET /portal/session.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","description":"Key name, trimmed before validation.","minLength":1,"maxLength":80},"scopes":{"type":"array","items":{"type":"string","enum":["dashboard:retail","dashboard:imports","dashboard:exports","dashboard:usda-ams"]},"minItems":1,"maxItems":4,"uniqueItems":true},"days":{"type":"integer","description":"Lifetime in days.","minimum":1,"maximum":90,"default":90}},"required":["name","scopes"]},"examples":{"example":{"summary":"example","value":{"name":"Imports integration","scopes":["dashboard:imports"],"days":1}}}}}},"responses":{"201":{"description":"Key created. Store the secret securely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"key":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","description":"UUID identifier.","format":"uuid"},"name":{"type":"string","description":"Display name."},"prefix":{"type":"string","description":"First 12 characters of the key."},"organization_id":{"type":"string","description":"Issuing organization."},"scopes":{"type":"array","items":{"type":"string","enum":["dashboard:retail","dashboard:imports","dashboard:exports","dashboard:usda-ams"]}},"state":{"type":"string","enum":["active","blocked","revoked"]},"reason":{"type":["string","null"]},"created_at":{"type":"string","description":"ISO 8601 timestamp with time zone.","format":"date-time"},"expires_at":{"type":"string","description":"ISO 8601 timestamp with time zone.","format":"date-time"},"last_used_at":{"type":["string","null"],"description":"ISO 8601 timestamp with time zone.","format":"date-time"}},"required":["id","name","prefix","organization_id","scopes","state","reason","created_at","expires_at","last_used_at"]},"secret":{"type":"string","description":"Full API key, displayed once.","pattern":"^bbi_[A-Za-z0-9_-]{43}$"}},"required":["key","secret"]},"examples":{"issued":{"summary":"issued","value":{"key":{"id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822","name":"Imports integration","prefix":"bbi_00000000","organization_id":"development","scopes":["dashboard:imports"],"state":"active","reason":null,"created_at":"2026-11-03T12:00:00.000Z","expires_at":"2026-11-04T12:00:00.000Z","last_used_at":null},"secret":"bbi_0000000000000000000000000000000000000000000"}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"The key and account do not have the required scope. Request the appropriate grant; a key does not expand account permissions.\n\nInvalid Origin or CSRF token in a portal mutation. Sign in to the portal again and use the current session's CSRF token.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"scope_forbidden":{"summary":"scope_forbidden","value":{"error":{"code":"scope_forbidden","message":"scope_forbidden","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"csrf_failed":{"summary":"csrf_failed","value":{"error":{"code":"csrf_failed","message":"csrf_failed","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"404":{"description":"The key does not belong to the account, does not exist, or cannot be rotated. Check the ID; rotation requires an active, unexpired key.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_not_found":{"summary":"key_not_found","value":{"error":{"code":"key_not_found","message":"key_not_found","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"409":{"description":"Maximum number of active keys reached. Revoke a key or rotate an existing one.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"active_key_limit":{"summary":"active_key_limit","value":{"error":{"code":"active_key_limit","message":"active_key_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"413":{"description":"Body exceeds the 8192-byte limit; HTTP error normalized by the current handler. Reduce the body size. This error's message is Request rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Request rejected","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"415":{"description":"Content-Type not accepted by the parser; HTTP error normalized by the current handler. Use application/json for bodies; omit Content-Type on bodyless DELETE/logout requests.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Request rejected","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.\n\nShared creation and rotation limit exceeded. Wait for Retry-After before creating or rotating again.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}},"key_creation_limit":{"summary":"key_creation_limit","value":{"error":{"code":"key_creation_limit","message":"key_creation_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/portal/keys/{id}":{"delete":{"tags":["Account portal"],"security":[{"PortalSession":[]}],"operationId":"revokePortalKey","summary":"Revoke an API key","description":"Revokes a key owned by the signed-in account. Revocation is permanent and repeating it returns the same state. Send an empty request without Content-Type.","parameters":[{"name":"id","in":"path","required":true,"description":"Public key ID obtained from the key list.","schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},{"name":"Origin","in":"header","required":true,"description":"Must match the configured portal origin exactly.","schema":{"type":"string"},"example":"https://di-industry.blueberry.org"},{"name":"X-CSRF-Token","in":"header","required":true,"description":"Token returned at login or in the X-CSRF-Token response header from GET /portal/session.","schema":{"type":"string"}}],"responses":{"200":{"description":"Key revoked.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","description":"UUID identifier.","format":"uuid"},"state":{"type":"string","const":"revoked"}},"required":["id","state"]},"examples":{"revoked":{"summary":"revoked","value":{"id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822","state":"revoked"}}}}}},"400":{"description":"Invalid parameter, JSON body, format, or combination. Review the specification; unknown and repeated parameters are rejected.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"code":"invalid_request","message":"Invalid request parameters","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"401":{"description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification. Check the account and issue a new credential if needed; do not retry indefinitely.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"unauthorized","value":{"error":{"code":"unauthorized","message":"Valid credentials required","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"403":{"description":"Invalid Origin or CSRF token in a portal mutation. Sign in to the portal again and use the current session's CSRF token.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"csrf_failed":{"summary":"csrf_failed","value":{"error":{"code":"csrf_failed","message":"csrf_failed","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"404":{"description":"The key does not belong to the account, does not exist, or cannot be rotated. Check the ID; rotation requires an active, unexpired key.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"key_not_found":{"summary":"key_not_found","value":{"error":{"code":"key_not_found","message":"key_not_found","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"429":{"description":"Key, user, organization, or IP budget exhausted. Honor Retry-After. Repeated violations of the key's own budgets may cause blocking.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Retry-After":{"schema":{"type":"integer","description":"Minimum wait in seconds before retrying.","minimum":1},"description":"Present for rate limits, concurrency limits, and key creation limits.","example":1}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"rate_limit","value":{"error":{"code":"rate_limit","message":"rate_limit","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"503":{"description":"Security Redis is unavailable or cannot enforce limits. The API denies access until controls recover; use bounded retries with backoff.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"security_unavailable":{"summary":"security_unavailable","value":{"error":{"code":"security_unavailable","message":"security_unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/health/live":{"get":{"operationId":"getLiveness","tags":["Health"],"summary":"Check liveness","description":"Checks that the HTTP process responds.","security":[],"responses":{"200":{"description":"Checks that the HTTP process responds.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"status":{"type":"string","const":"ok"}},"required":["status"]},"examples":{"ok":{"summary":"ok","value":{"status":"ok"}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/health/ready":{"get":{"operationId":"getReadiness","tags":["Health"],"summary":"Check readiness","description":"Checks the PostgreSQL migrations table and both Redis connections. It does not query the dashboard data source.","security":[],"responses":{"200":{"description":"Checks the PostgreSQL migrations table and both Redis connections. It does not query the dashboard data source.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"status":{"type":"string","const":"ready"}},"required":["status"]},"examples":{"ready":{"summary":"ready","value":{"status":"ready"}}}}}},"503":{"description":"At least one dependency check failed.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"status":{"type":"string","const":"unavailable"}},"required":["status"]},"examples":{"unavailable":{"summary":"unavailable","value":{"status":"unavailable"}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/openapi.json":{"get":{"operationId":"getPublicOpenApi","tags":["Documentation"],"summary":"Get the public OpenAPI specification","description":"OpenAPI 3.1.1 document for the current installation, with a same-origin server URL.","security":[],"parameters":[{"name":"download","in":"query","required":false,"description":"Set to 1 to download the same document as an attachment.","schema":{"type":"string","const":"1"},"example":"1"}],"responses":{"200":{"description":"OpenAPI 3.1.1 document for the current installation, with a same-origin server URL.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Content-Disposition":{"schema":{"type":"string"},"description":"Present when download=1.","example":"attachment; filename=\"blueberries-openapi.json\""}},"content":{"application/json":{"schema":{"type":"object","required":["openapi","info","paths"],"properties":{"openapi":{"const":"3.1.1"},"info":{"type":"object"},"paths":{"type":"object"}}},"examples":{"current":{"summary":"Complete document from this installation","externalValue":"/openapi.json"}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/postman.collection.json":{"get":{"operationId":"getPostmanCollection","tags":["Documentation"],"summary":"Get the Postman collection","description":"Postman 2.1 collection for the current installation, with empty credential variables.","security":[],"parameters":[{"name":"download","in":"query","required":false,"description":"Set to 1 to download the same document as an attachment.","schema":{"type":"string","const":"1"},"example":"1"}],"responses":{"200":{"description":"Postman 2.1 collection for the current installation, with empty credential variables.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Content-Disposition":{"schema":{"type":"string"},"description":"Present when download=1.","example":"attachment; filename=\"blueberries-postman.collection.json\""}},"content":{"application/json":{"schema":{"type":"object","required":["info","item","variable"],"properties":{"info":{"type":"object"},"item":{"type":"array"},"variable":{"type":"array"}}},"examples":{"current":{"summary":"Complete document from this installation","externalValue":"/postman.collection.json"}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}},"/data-dictionary.json":{"get":{"operationId":"getDataDictionary","tags":["Documentation"],"summary":"Get the data dictionary","description":"Dashboard definitions keyed by dashboard slug, including tile IDs, field schemas, and calculation notes.","security":[],"parameters":[{"name":"download","in":"query","required":false,"description":"Set to 1 to download the same document as an attachment.","schema":{"type":"string","const":"1"},"example":"1"}],"responses":{"200":{"description":"Dashboard definitions keyed by dashboard slug, including tile IDs, field schemas, and calculation notes.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"},"Content-Disposition":{"schema":{"type":"string"},"description":"Present when download=1.","example":"attachment; filename=\"blueberries-data-dictionary.json\""}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"retail":{"type":"object","required":["label","description","tiles"],"properties":{"label":{"type":"string"},"description":{"type":"string"},"tiles":{"type":"array","items":{"type":"object"}}}},"imports":{"type":"object","required":["label","description","tiles"],"properties":{"label":{"type":"string"},"description":{"type":"string"},"tiles":{"type":"array","items":{"type":"object"}}}},"exports":{"type":"object","required":["label","description","tiles"],"properties":{"label":{"type":"string"},"description":{"type":"string"},"tiles":{"type":"array","items":{"type":"object"}}}},"usda-ams":{"type":"object","required":["label","description","tiles"],"properties":{"label":{"type":"string"},"description":{"type":"string"},"tiles":{"type":"array","items":{"type":"object"}}}}},"required":["retail","imports","exports","usda-ams"]},"examples":{"current":{"summary":"Complete document from this installation","externalValue":"/data-dictionary.json"}}}}},"500":{"description":"Unexpected internal error or persistence failure. Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}},"default":{"description":"Unexpected HTTP failure handled by the application. Network/proxy errors may not use this envelope.","headers":{"X-Request-ID":{"schema":{"type":"string","description":"UUID identifier.","format":"uuid"},"description":"Application-generated identifier for this request.","example":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"},"Cache-Control":{"schema":{"type":"string"},"description":"API responses must not be stored by browsers or proxies. Redis caching is internal.","example":"no-store"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unexpected":{"summary":"unexpected","value":{"error":{"code":"internal_error","message":"Service unavailable","request_id":"c98132c7-dd07-4ed6-b1fc-a27eec09d822"}}}}}}}}}}},"components":{"schemas":{"Error":{"type":"object","additionalProperties":false,"properties":{"error":{"type":"object","additionalProperties":false,"properties":{"code":{"type":"string","description":"Stable application code.","enum":["invalid_request","credentials_in_query","unauthorized","scope_forbidden","csrf_failed","origin_forbidden","not_found","key_not_found","active_key_limit","key_revoked","internal_error","rate_limit","concurrency_limit","key_creation_limit","glueup_pending_confirmation","security_unavailable","cache_unavailable","source_busy","source_unavailable"]},"message":{"type":"string","description":"Sanitized message. Consumers must use code for logic; message text is not a stable contract."},"request_id":{"type":"string","description":"UUID identifier.","format":"uuid"}},"required":["code","message","request_id"]}},"required":["error"]},"FilterValue":{"type":"object","additionalProperties":false,"properties":{"value":{"type":"string"},"label":{"type":"string"}},"required":["value","label"]},"Filter":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","description":"Human-readable filter name."},"dimension":{"type":"string","description":"Accepted query parameter name."},"values":{"type":"array","items":{"$ref":"#/components/schemas/FilterValue"}}},"required":["name","dimension","values"]},"DemoTile":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"example"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"properties":{"date":{"type":"string","format":"date"},"value":{"type":"number"}},"required":["date","value"]}}},"required":["id","title","total","has_more","data"]},"RetailRow6287":{"type":"object","additionalProperties":false,"required":["spins_all_iq.dynamic_measure_fresh_label","spins_all_iq.dynamic_measure_filter_fresh"],"properties":{"spins_all_iq.dynamic_measure_fresh_label":{"type":"string","description":"Calculated label based on the metric; descriptive text, not a numeric value.","examples":["Total LB (Fresh)"]},"spins_all_iq.dynamic_measure_filter_fresh":{"type":["number","string","null"],"description":"Total of the selected metric for Fresh. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"selected metric (lb / USD / estimated units)","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"RetailTile6287":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6287"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6287"}}},"required":["id","title","total","has_more","data"],"description":"Total of the selected metric for Fresh."},"RetailRow6289":{"type":"object","additionalProperties":false,"required":["spins_all_iq.dynamic_measure_frozen_label","spins_all_iq.dynamic_measure_filter_frozen"],"properties":{"spins_all_iq.dynamic_measure_frozen_label":{"type":"string","description":"Calculated label based on the metric; descriptive text, not a numeric value.","examples":["Total LB (Frozen)"]},"spins_all_iq.dynamic_measure_filter_frozen":{"type":["number","string","null"],"description":"Total of the selected metric for Frozen. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"selected metric (lb / USD / estimated units)","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"RetailTile6289":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6289"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6289"}}},"required":["id","title","total","has_more","data"],"description":"Total of the selected metric for Frozen."},"RetailRow6292":{"type":"object","additionalProperties":false,"required":["spins_all_iq.dynamic_measure_fresh_label_perc","spins_all_iq.dynamic_measure_filter_fresh_perc"],"properties":{"spins_all_iq.dynamic_measure_fresh_label_perc":{"type":"string","description":"Calculated label based on the metric; descriptive text, not a numeric value.","examples":["% of Total LB (Fresh)"]},"spins_all_iq.dynamic_measure_filter_fresh_perc":{"type":["number","string","null"],"description":"Fresh share of total volume in lb. The formula uses lb even when Dollars or Units is selected. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"percent","examples":[25],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"RetailTile6292":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6292"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6292"}}},"required":["id","title","total","has_more","data"],"description":"Fresh share of total volume in lb. The formula uses lb even when Dollars or Units is selected."},"RetailRow6293":{"type":"object","additionalProperties":false,"required":["spins_all_iq.dynamic_measure_fresh_label_yoy","spins_all_iq.dynamic_measure_filter_fresh_yoy"],"properties":{"spins_all_iq.dynamic_measure_fresh_label_yoy":{"type":"string","description":"Calculated label based on the metric; descriptive text, not a numeric value.","examples":["LB % Change YoY (Fresh)"]},"spins_all_iq.dynamic_measure_filter_fresh_yoy":{"type":["number","string","null"],"description":"Fresh year-over-year change: 100 × (current − previous) / previous. Uses dollars for Dollars and lb for LB and Units. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"percent","examples":[25],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"RetailTile6293":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6293"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6293"}}},"required":["id","title","total","has_more","data"],"description":"Fresh year-over-year change: 100 × (current − previous) / previous. Uses dollars for Dollars and lb for LB and Units."},"RetailRow6294":{"type":"object","additionalProperties":false,"required":["spins_all_iq.dynamic_measure_frozen_label_yoy","spins_all_iq.dynamic_measure_filter_frozen_yoy"],"properties":{"spins_all_iq.dynamic_measure_frozen_label_yoy":{"type":"string","description":"Calculated label based on the metric; descriptive text, not a numeric value.","examples":["LB % Change YoY (Frozen)"]},"spins_all_iq.dynamic_measure_filter_frozen_yoy":{"type":["number","string","null"],"description":"Frozen year-over-year change: 100 × (current − previous) / previous. Uses dollars for Dollars and lb for LB and Units. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"percent","examples":[25],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"RetailTile6294":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6294"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6294"}}},"required":["id","title","total","has_more","data"],"description":"Frozen year-over-year change: 100 × (current − previous) / previous. Uses dollars for Dollars and lb for LB and Units."},"RetailRow6295":{"type":"object","additionalProperties":false,"required":["spins_all_iq.dynamic_measure_frozen_label_perc","spins_all_iq.dynamic_measure_filter_frozen_perc"],"properties":{"spins_all_iq.dynamic_measure_frozen_label_perc":{"type":"string","description":"Calculated label based on the metric; descriptive text, not a numeric value.","examples":["% of Total LB (Frozen)"]},"spins_all_iq.dynamic_measure_filter_frozen_perc":{"type":["number","string","null"],"description":"Frozen share of total volume in lb. The formula uses lb even when Dollars or Units is selected. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"percent","examples":[25],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"RetailTile6295":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6295"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6295"}}},"required":["id","title","total","has_more","data"],"description":"Frozen share of total volume in lb. The formula uses lb even when Dollars or Units is selected."},"RetailRow6298":{"type":"object","additionalProperties":false,"required":["spins_all_iq.base_size_filter","spins_all_iq.dynamic_measure_filter","spins_all_iq.volume_lbs","spins_all_iq.total_dollars","spins_all_iq.units","spins_all_iq.price_usd_lb"],"properties":{"spins_all_iq.base_size_filter":{"type":["string","null"],"description":"Source-reported size. The adapter extracts the leading number to estimate Units.","examples":["6 oz"]},"spins_all_iq.dynamic_measure_filter":{"type":["number","string","null"],"description":"SUM of the selected measure. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"selected metric (lb / USD / estimated units)","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"spins_all_iq.volume_lbs":{"type":["number","string","null"],"description":"SUM(total_lbs). null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"spins_all_iq.total_dollars":{"type":["number","string","null"],"description":"SUM(total_dollars). null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD","examples":[250],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"spins_all_iq.units":{"type":["number","string","null"],"description":"SUM(total_lbs / leading number in base_size); estimate preserved from the adapter. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"estimated units","examples":[16.67],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"spins_all_iq.price_usd_lb":{"type":["number","string","null"],"description":"SUM(total_dollars) / SUM(total_lbs), weighted by volume. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD/lb","examples":[2.5],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"RetailTile6298":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6298"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6298"}}},"required":["id","title","total","has_more","data"],"description":"Aggregated by size. Units is estimated as total_lbs / the number extracted from base_size; the adapter performs no additional oz/lb conversion."},"RetailRow6299":{"type":"object","additionalProperties":false,"required":["spins_all_iq.price_usd_lb_prior","spins_all_iq.price_usd_lb_current","spins_all_iq.week_ending"],"properties":{"spins_all_iq.price_usd_lb_prior":{"type":["number","string","null"],"description":"SUM(total_dollars_ya) / SUM(total_lbs_ya). null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD/lb","examples":[2],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"spins_all_iq.price_usd_lb_current":{"type":["number","string","null"],"description":"SUM(total_dollars) / SUM(total_lbs). null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD/lb","examples":[2.5],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"spins_all_iq.week_ending":{"type":"string","description":"Weekly source date, serialized as YYYY-MM-DD in UTC. Value serialized by the source CAST; YYYY-MM-DD is the example, but the underlying temporal type and format require validation against real BigQuery data.","examples":["2026-01-03"]}}},"RetailTile6299":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6299"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6299"}}},"required":["id","title","total","has_more","data"],"description":"Weekly series of volume-weighted prices; window aligned to Saturday."},"RetailRow6300":{"type":"object","additionalProperties":false,"required":["spins_all_iq.max_week_start","spins_all_iq.min_week_start"],"properties":{"spins_all_iq.max_week_start":{"type":["string","null"],"description":"Latest week_ending in the requested window. Value serialized by the source CAST; YYYY-MM-DD is the example, but the underlying temporal type and format require validation against real BigQuery data.","examples":["2026-01-03"]},"spins_all_iq.min_week_start":{"type":["string","null"],"description":"Earliest week_ending in the requested window. Value serialized by the source CAST; YYYY-MM-DD is the example, but the underlying temporal type and format require validation against real BigQuery data.","examples":["2025-01-04"]}}},"RetailTile6300":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6300"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6300"}}},"required":["id","title","total","has_more","data"],"description":"Maximum and minimum dates in the selected weekly series; the legacy title is preserved."},"RetailRow6302":{"type":"object","additionalProperties":false,"required":["spins_all_iq.week_ending","spins_all_iq.dynamic_measure_filter_prior","spins_all_iq.dynamic_measure_filter_updated"],"properties":{"spins_all_iq.week_ending":{"type":"string","description":"Weekly source date. Value serialized by the source CAST; YYYY-MM-DD is the example, but the underlying temporal type and format require validation against real BigQuery data.","examples":["2026-01-03"]},"spins_all_iq.dynamic_measure_filter_prior":{"type":["number","string","null"],"description":"Sum of the measure for the previous comparable period; Units uses the same size-based estimate. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"selected metric (lb / USD / estimated units)","examples":[80],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"spins_all_iq.dynamic_measure_filter_updated":{"type":["number","string","null"],"description":"Sum of the current measure; Units uses the same size-based estimate. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"selected metric (lb / USD / estimated units)","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"RetailTile6302":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"6302"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RetailRow6302"}}},"required":["id","title","total","has_more","data"],"description":"Weekly series of the selected metric. The previous measure uses _ya fields."},"RetailSourceDashboard":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"retail"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Filters echoed by the adapter using legacy names. They may differ from query names and omit base_size_filter; see the example and dictionary."},"fetched_at":{"type":"string","description":"API retrieval timestamp; the cache preserves it. This is not the source update time.","format":"date-time"},"timezone":{"type":"string","const":"UTC"},"page":{"type":"integer","description":"Requested page, applied independently to each tile.","minimum":1,"maximum":100},"page_size":{"type":"integer","description":"Maximum rows per tile on this page.","minimum":1,"maximum":100},"tiles":{"type":"array","minItems":10,"maxItems":10,"items":{"oneOf":[{"$ref":"#/components/schemas/RetailTile6287"},{"$ref":"#/components/schemas/RetailTile6289"},{"$ref":"#/components/schemas/RetailTile6292"},{"$ref":"#/components/schemas/RetailTile6293"},{"$ref":"#/components/schemas/RetailTile6294"},{"$ref":"#/components/schemas/RetailTile6295"},{"$ref":"#/components/schemas/RetailTile6298"},{"$ref":"#/components/schemas/RetailTile6299"},{"$ref":"#/components/schemas/RetailTile6300"},{"$ref":"#/components/schemas/RetailTile6302"}],"discriminator":{"propertyName":"id","mapping":{"6287":"#/components/schemas/RetailTile6287","6289":"#/components/schemas/RetailTile6289","6292":"#/components/schemas/RetailTile6292","6293":"#/components/schemas/RetailTile6293","6294":"#/components/schemas/RetailTile6294","6295":"#/components/schemas/RetailTile6295","6298":"#/components/schemas/RetailTile6298","6299":"#/components/schemas/RetailTile6299","6300":"#/components/schemas/RetailTile6300","6302":"#/components/schemas/RetailTile6302"}}}}},"required":["dashboard","filters","fetched_at","timezone","page","page_size","tiles"],"description":"Format produced by the adapters. Examples use synthetic data; real data has not yet been validated."},"RetailDemoDashboard":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"retail"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Filters echoed by the adapter using legacy names. They may differ from query names and omit base_size_filter; see the example and dictionary."},"fetched_at":{"type":"string","description":"API retrieval timestamp; the cache preserves it. This is not the source update time.","format":"date-time"},"timezone":{"type":"string","const":"UTC"},"page":{"type":"integer","description":"Requested page, applied independently to each tile.","minimum":1,"maximum":100},"page_size":{"type":"integer","description":"Maximum rows per tile on this page.","minimum":1,"maximum":100},"demo":{"type":"boolean","const":true},"tiles":{"type":"array","minItems":1,"maxItems":1,"items":{"$ref":"#/components/schemas/DemoTile"}}},"required":["dashboard","filters","fetched_at","timezone","page","page_size","demo","tiles"],"description":"Response from the current demo provider. Its single generic tile does not represent real metrics."},"RetailDashboard":{"oneOf":[{"$ref":"#/components/schemas/RetailSourceDashboard"},{"$ref":"#/components/schemas/RetailDemoDashboard"}],"description":"Two explicitly separate formats: data adapter and demo. Do not mix tiles across modes."},"RetailFilterResponse":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"retail"},"filters":{"type":"array","items":{"$ref":"#/components/schemas/Filter"}},"demo":{"type":"boolean","const":true}},"required":["dashboard","filters"]},"ImportsRow1258":{"type":"object","additionalProperties":false,"required":["gats_census_trade.country_name","gats_census_trade.total_pounds_current"],"properties":{"gats_census_trade.country_name":{"type":"string","description":"Country in the source-reported aggregation.","examples":["Example country"]},"gats_census_trade.total_pounds_current":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Fresh Conventional Blueberries","Fresh Organic Blueberries","Fresh Wild Blueberries","Frozen Conventional Blueberries","Frozen Organic Blueberries","Frozen Wild Blueberries","Dried Highbush Blueberries","Dried Wild Blueberries"],"properties":{"Fresh Conventional Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Conventional Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Fresh Organic Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Organic Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Fresh Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Conventional Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Conventional Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Organic Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Organic Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Dried Highbush Blueberries":{"type":["number","string","null"],"description":"Volume for category Dried Highbush Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Dried Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Dried Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}},"description":"Map of the eight fixed blueberry categories. Categories without a measure return null."}},"description":"Volume in lb by berry category; not a scalar number."}}},"ImportsTile1258":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1258"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ImportsRow1258"}}},"required":["id","title","total","has_more","data"],"description":"Current volume by country and berry category. Rows for the first day of the month in the pre-aggregated table."},"ImportsRow1259":{"type":"object","additionalProperties":false,"required":["gats_census_trade.country_name","gats_census_trade.total_quantity_1"],"properties":{"gats_census_trade.country_name":{"type":"string","description":"Country in the source-reported aggregation.","examples":["Example country"]},"gats_census_trade.total_quantity_1":{"type":["number","string","null"],"description":"SUM(pounds) for rows whose week_ending day is 1. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"ImportsTile1259":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1259"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ImportsRow1259"}}},"required":["id","title","total","has_more","data"],"description":"Total current volume by country."},"ImportsRow1261":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_","gats_census_trade.hs10_code_type","gats_census_trade.total_pounds_prior","gats_census_trade.total_pounds_change","gats_census_trade.total_pounds_current"],"properties":{"gats_census_trade.hs10_code_":{"type":"string","description":"Ten-digit HS code, as a string to preserve leading zeros.","examples":["0810400024"]},"gats_census_trade.hs10_code_type":{"type":"string","description":"Source-reported berry category.","examples":["Fresh Wild Blueberries"]},"gats_census_trade.total_pounds_prior":{"type":["number","string","null"],"description":"SUM(pounds_ya) for DAY != 1 rows. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[80],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"gats_census_trade.total_pounds_change":{"type":["number","string","null"],"description":"(current value − previous value) / previous value; 0.25 means +25%, without multiplication by 100. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"ratio","examples":[0.25],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"gats_census_trade.total_pounds_current":{"type":["number","string","null"],"description":"SUM(pounds) for DAY = 1 rows. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"ImportsTile1261":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1261"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ImportsRow1261"}}},"required":["id","title","total","has_more","data"],"description":"Comparison by HS code: current uses DAY=1 rows; previous uses pounds_ya from other rows."},"ImportsRow1262":{"type":"object","additionalProperties":false,"required":["gats_census_trade.date_in_period_month","gats_census_trade.total_pounds_current"],"properties":{"gats_census_trade.date_in_period_month":{"type":"string","description":"Source month in YYYY-MM format.","examples":["2026-01"],"pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"gats_census_trade.total_pounds_current":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Fresh Conventional Blueberries","Fresh Organic Blueberries","Fresh Wild Blueberries","Frozen Conventional Blueberries","Frozen Organic Blueberries","Frozen Wild Blueberries","Dried Highbush Blueberries","Dried Wild Blueberries"],"properties":{"Fresh Conventional Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Conventional Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Fresh Organic Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Organic Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Fresh Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Conventional Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Conventional Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Organic Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Organic Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Dried Highbush Blueberries":{"type":["number","string","null"],"description":"Volume for category Dried Highbush Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Dried Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Dried Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}},"description":"Map of the eight fixed blueberry categories. Categories without a measure return null."}},"description":"Volume in lb by berry category; not a scalar number."}}},"ImportsTile1262":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1262"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ImportsRow1262"}}},"required":["id","title","total","has_more","data"],"description":"Current monthly volume by berry category."},"ImportsRow1263":{"type":"object","additionalProperties":false,"required":["gats_census_trade.date_in_period_month","gats_census_trade.total_pounds_current"],"properties":{"gats_census_trade.date_in_period_month":{"type":"string","description":"Source month in YYYY-MM format.","examples":["2026-01"],"pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"gats_census_trade.total_pounds_current":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_"],"properties":{"gats_census_trade.hs10_code_":{"type":"object","additionalProperties":false,"required":["0810400024","0810400026","0810400029","0811902024","0811902030","0811902040","0813402010","0813402020"],"properties":{"0810400024":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Fresh Wild Blueberries"],"properties":{"Fresh Wild Blueberries":{"type":["number","string","null"],"description":"Current volume for HS code 0810400024 null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}}}},"0810400026":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Fresh Organic Blueberries"],"properties":{"Fresh Organic Blueberries":{"type":["number","string","null"],"description":"Current volume for HS code 0810400026 null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}}}},"0810400029":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Fresh Conventional Blueberries"],"properties":{"Fresh Conventional Blueberries":{"type":["number","string","null"],"description":"Current volume for HS code 0810400029 null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}}}},"0811902024":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Frozen Wild Blueberries"],"properties":{"Frozen Wild Blueberries":{"type":["number","string","null"],"description":"Current volume for HS code 0811902024 null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}}}},"0811902030":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Frozen Organic Blueberries"],"properties":{"Frozen Organic Blueberries":{"type":["number","string","null"],"description":"Current volume for HS code 0811902030 null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}}}},"0811902040":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Frozen Conventional Blueberries"],"properties":{"Frozen Conventional Blueberries":{"type":["number","string","null"],"description":"Current volume for HS code 0811902040 null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}}}},"0813402010":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Dried Wild Blueberries"],"properties":{"Dried Wild Blueberries":{"type":["number","string","null"],"description":"Current volume for HS code 0813402010 null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}}}},"0813402020":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Dried Highbush Blueberries"],"properties":{"Dried Highbush Blueberries":{"type":["number","string","null"],"description":"Current volume for HS code 0813402020 null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}}}}},"description":"The eight fixed codes mapped by the adapter."}}}}},"ImportsTile1263":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1263"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ImportsRow1263"}}},"required":["id","title","total","has_more","data"],"description":"Monthly pivot by HS code and category. Nested structure; not a scalar measure."},"ImportsRow1265":{"type":"object","additionalProperties":false,"required":["gats_census_trade.max_week_start"],"properties":{"gats_census_trade.max_week_start":{"type":["string","null"],"description":"MAX(week_ending) for DAY=1 rows. Value serialized by the source CAST; YYYY-MM-DD is the example, but the underlying temporal type and format require validation against real BigQuery data.","examples":["2026-01-01"]}}},"ImportsTile1265":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1265"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ImportsRow1265"}}},"required":["id","title","total","has_more","data"],"description":"Latest available current date, preserving the legacy title."},"ImportsSourceDashboard":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"imports"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Filters echoed by the adapter using legacy names. They may differ from query names and omit base_size_filter; see the example and dictionary."},"fetched_at":{"type":"string","description":"API retrieval timestamp; the cache preserves it. This is not the source update time.","format":"date-time"},"timezone":{"type":"string","const":"UTC"},"page":{"type":"integer","description":"Requested page, applied independently to each tile.","minimum":1,"maximum":100},"page_size":{"type":"integer","description":"Maximum rows per tile on this page.","minimum":1,"maximum":100},"tiles":{"type":"array","minItems":6,"maxItems":6,"items":{"oneOf":[{"$ref":"#/components/schemas/ImportsTile1258"},{"$ref":"#/components/schemas/ImportsTile1259"},{"$ref":"#/components/schemas/ImportsTile1261"},{"$ref":"#/components/schemas/ImportsTile1262"},{"$ref":"#/components/schemas/ImportsTile1263"},{"$ref":"#/components/schemas/ImportsTile1265"}],"discriminator":{"propertyName":"id","mapping":{"1258":"#/components/schemas/ImportsTile1258","1259":"#/components/schemas/ImportsTile1259","1261":"#/components/schemas/ImportsTile1261","1262":"#/components/schemas/ImportsTile1262","1263":"#/components/schemas/ImportsTile1263","1265":"#/components/schemas/ImportsTile1265"}}}}},"required":["dashboard","filters","fetched_at","timezone","page","page_size","tiles"],"description":"Format produced by the adapters. Examples use synthetic data; real data has not yet been validated."},"ImportsDemoDashboard":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"imports"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Filters echoed by the adapter using legacy names. They may differ from query names and omit base_size_filter; see the example and dictionary."},"fetched_at":{"type":"string","description":"API retrieval timestamp; the cache preserves it. This is not the source update time.","format":"date-time"},"timezone":{"type":"string","const":"UTC"},"page":{"type":"integer","description":"Requested page, applied independently to each tile.","minimum":1,"maximum":100},"page_size":{"type":"integer","description":"Maximum rows per tile on this page.","minimum":1,"maximum":100},"demo":{"type":"boolean","const":true},"tiles":{"type":"array","minItems":1,"maxItems":1,"items":{"$ref":"#/components/schemas/DemoTile"}}},"required":["dashboard","filters","fetched_at","timezone","page","page_size","demo","tiles"],"description":"Response from the current demo provider. Its single generic tile does not represent real metrics."},"ImportsDashboard":{"oneOf":[{"$ref":"#/components/schemas/ImportsSourceDashboard"},{"$ref":"#/components/schemas/ImportsDemoDashboard"}],"description":"Two explicitly separate formats: data adapter and demo. Do not mix tiles across modes."},"ImportsFilterResponse":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"imports"},"filters":{"type":"array","items":{"$ref":"#/components/schemas/Filter"}},"demo":{"type":"boolean","const":true}},"required":["dashboard","filters"]},"ExportsRow1301":{"type":"object","additionalProperties":false,"required":["gats_census_trade.reporting_month","gats_census_trade.total_pounds_current"],"properties":{"gats_census_trade.reporting_month":{"type":"string","description":"Source month in YYYY-MM format.","examples":["2026-01"],"pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"gats_census_trade.total_pounds_current":{"type":"object","additionalProperties":false,"required":["gats_census_trade.hs10_code_type"],"properties":{"gats_census_trade.hs10_code_type":{"type":"object","additionalProperties":false,"required":["Fresh Conventional Blueberries","Fresh Organic Blueberries","Fresh Wild Blueberries","Frozen Conventional Blueberries","Frozen Organic Blueberries","Frozen Wild Blueberries","Dried Highbush Blueberries","Dried Wild Blueberries"],"properties":{"Fresh Conventional Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Conventional Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Fresh Organic Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Organic Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Fresh Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Fresh Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Conventional Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Conventional Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Organic Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Organic Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Frozen Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Frozen Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Dried Highbush Blueberries":{"type":["number","string","null"],"description":"Volume for category Dried Highbush Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"Dried Wild Blueberries":{"type":["number","string","null"],"description":"Volume for category Dried Wild Blueberries null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[10],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}},"description":"Map of the eight fixed blueberry categories. Categories without a measure return null."}},"description":"Volume in lb by berry category; not a scalar number."}}},"ExportsTile1301":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1301"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ExportsRow1301"}}},"required":["id","title","total","has_more","data"],"description":"Monthly export volume (flow_type Export) by berry category."},"ExportsRow1302":{"type":"object","additionalProperties":false,"required":["gats_census_trade.country_name","gats_census_trade.total_quantity_1"],"properties":{"gats_census_trade.country_name":{"type":"string","description":"Country in the source-reported aggregation.","examples":["Example country"]},"gats_census_trade.total_quantity_1":{"type":["number","string","null"],"description":"SUM(pounds) for exports. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"ExportsTile1302":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1302"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ExportsRow1302"}}},"required":["id","title","total","has_more","data"],"description":"Export volume by country."},"ExportsRow1303":{"type":"object","additionalProperties":false,"required":["gats_census_trade.reporting_month","gats_census_trade.total_quantity_1","gats_census_trade.total_quantity_1_ya"],"properties":{"gats_census_trade.reporting_month":{"type":"string","description":"Source month in YYYY-MM format.","examples":["2026-01"],"pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"gats_census_trade.total_quantity_1":{"type":["number","string","null"],"description":"SUM(pounds) for exports in the month. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"gats_census_trade.total_quantity_1_ya":{"type":["number","string","null"],"description":"SUM(pounds_ya) in the month. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[80],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"ExportsTile1303":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1303"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ExportsRow1303"}}},"required":["id","title","total","has_more","data"],"description":"Despite “avg” in the legacy title, SQL calculates SUM, not an average."},"ExportsRow1304":{"type":"object","additionalProperties":false,"required":["gats_census_trade.country_name","gats_census_trade.total_quantity_1"],"properties":{"gats_census_trade.country_name":{"type":"string","description":"Country in the source-reported aggregation.","examples":["Example country"]},"gats_census_trade.total_quantity_1":{"type":["number","string","null"],"description":"SUM(pounds) for exports. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"ExportsTile1304":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1304"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ExportsRow1304"}}},"required":["id","title","total","has_more","data"],"description":"Same country projection as tile 1302, preserved from the adapter."},"ExportsRow1305":{"type":"object","additionalProperties":false,"required":["gats_census_trade.country_name","gats_census_trade.total_pounds_current","gats_census_trade.total_pounds_prior","gats_census_trade.total_pounds_change","gats_census_trade.total_dollars_current","gats_census_trade.total_dollars_prior","gats_census_trade.total_dollars_change"],"properties":{"gats_census_trade.country_name":{"type":"string","description":"Country in the source-reported aggregation.","examples":["Example country"]},"gats_census_trade.total_pounds_current":{"type":["number","string","null"],"description":"Current SUM(pounds). null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"gats_census_trade.total_pounds_prior":{"type":["number","string","null"],"description":"Previous comparable SUM(pounds_ya). null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[80],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"gats_census_trade.total_pounds_change":{"type":["number","string","null"],"description":"(current value − previous value) / previous value; 0.25 means +25%, without multiplication by 100. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"ratio","examples":[0.25],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"gats_census_trade.total_dollars_current":{"type":["number","string","null"],"description":"Current SUM(dollars). null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD","examples":[250],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"gats_census_trade.total_dollars_prior":{"type":["number","string","null"],"description":"Previous comparable SUM(dollars_ya). null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD","examples":[200],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"gats_census_trade.total_dollars_change":{"type":["number","string","null"],"description":"(current value − previous value) / previous value; 0.25 means +25%, without multiplication by 100. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"ratio","examples":[0.25],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"ExportsTile1305":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"1305"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ExportsRow1305"}}},"required":["id","title","total","has_more","data"],"description":"Source aggregation by country. SQL does not apply LIMIT; this is not a top N list. The API sorts lexicographically for pagination."},"ExportsSourceDashboard":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"exports"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Filters echoed by the adapter using legacy names. They may differ from query names and omit base_size_filter; see the example and dictionary."},"fetched_at":{"type":"string","description":"API retrieval timestamp; the cache preserves it. This is not the source update time.","format":"date-time"},"timezone":{"type":"string","const":"UTC"},"page":{"type":"integer","description":"Requested page, applied independently to each tile.","minimum":1,"maximum":100},"page_size":{"type":"integer","description":"Maximum rows per tile on this page.","minimum":1,"maximum":100},"tiles":{"type":"array","minItems":5,"maxItems":5,"items":{"oneOf":[{"$ref":"#/components/schemas/ExportsTile1301"},{"$ref":"#/components/schemas/ExportsTile1302"},{"$ref":"#/components/schemas/ExportsTile1303"},{"$ref":"#/components/schemas/ExportsTile1304"},{"$ref":"#/components/schemas/ExportsTile1305"}],"discriminator":{"propertyName":"id","mapping":{"1301":"#/components/schemas/ExportsTile1301","1302":"#/components/schemas/ExportsTile1302","1303":"#/components/schemas/ExportsTile1303","1304":"#/components/schemas/ExportsTile1304","1305":"#/components/schemas/ExportsTile1305"}}}}},"required":["dashboard","filters","fetched_at","timezone","page","page_size","tiles"],"description":"Format produced by the adapters. Examples use synthetic data; real data has not yet been validated."},"ExportsDemoDashboard":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"exports"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Filters echoed by the adapter using legacy names. They may differ from query names and omit base_size_filter; see the example and dictionary."},"fetched_at":{"type":"string","description":"API retrieval timestamp; the cache preserves it. This is not the source update time.","format":"date-time"},"timezone":{"type":"string","const":"UTC"},"page":{"type":"integer","description":"Requested page, applied independently to each tile.","minimum":1,"maximum":100},"page_size":{"type":"integer","description":"Maximum rows per tile on this page.","minimum":1,"maximum":100},"demo":{"type":"boolean","const":true},"tiles":{"type":"array","minItems":1,"maxItems":1,"items":{"$ref":"#/components/schemas/DemoTile"}}},"required":["dashboard","filters","fetched_at","timezone","page","page_size","demo","tiles"],"description":"Response from the current demo provider. Its single generic tile does not represent real metrics."},"ExportsDashboard":{"oneOf":[{"$ref":"#/components/schemas/ExportsSourceDashboard"},{"$ref":"#/components/schemas/ExportsDemoDashboard"}],"description":"Two explicitly separate formats: data adapter and demo. Do not mix tiles across modes."},"ExportsFilterResponse":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"exports"},"filters":{"type":"array","items":{"$ref":"#/components/schemas/Filter"}},"demo":{"type":"boolean","const":true}},"required":["dashboard","filters"]},"UsdaAmsRow8274":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.price"],"properties":{"usda_region_pricing_movement.price":{"type":["number","string","null"],"description":"AVG(price_per_lb), excluding prices <= 0. Arithmetic mean, not weighted by volume. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD/lb","examples":[2.5],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"UsdaAmsTile8274":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"8274"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/UsdaAmsRow8274"}}},"required":["id","title","total","has_more","data"],"description":"Arithmetic mean FOB price in the nominal window aligned to Saturday."},"UsdaAmsRow8275":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.data_date"],"properties":{"usda_region_pricing_movement.data_date":{"type":"string","description":"Source week_ending in YYYY-MM-DD format. Value serialized by the source CAST; YYYY-MM-DD is the example, but the underlying temporal type and format require validation against real BigQuery data.","examples":["2026-01-03"]}}},"UsdaAmsTile8275":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"8275"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/UsdaAmsRow8275"}}},"required":["id","title","total","has_more","data"],"description":"Distinct dates in the window. Not just one row containing the latest date."},"UsdaAmsRow8276":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.price","usda_region_pricing_movement.data_month"],"properties":{"usda_region_pricing_movement.price":{"type":["number","string","null"],"description":"AVG(price_per_lb), excluding prices <= 0. Arithmetic mean, not weighted by volume. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD/lb","examples":[2.5],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"usda_region_pricing_movement.data_month":{"type":"string","description":"Source month in YYYY-MM format.","examples":["2026-01"],"pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}}},"UsdaAmsTile8276":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"8276"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/UsdaAmsRow8276"}}},"required":["id","title","total","has_more","data"],"description":"Legacy title; returns average price by month. The adapter does not calculate YoY change in this tile."},"UsdaAmsRow8277":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.data_month","usda_region_pricing_movement.movement_lbs"],"properties":{"usda_region_pricing_movement.data_month":{"type":"string","description":"Source month in YYYY-MM format.","examples":["2026-01"],"pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"usda_region_pricing_movement.movement_lbs":{"type":["number","string","null"],"description":"SUM(total_volume) for the aggregated rows. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"UsdaAmsTile8277":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"8277"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/UsdaAmsRow8277"}}},"required":["id","title","total","has_more","data"],"description":"Legacy title; returns summed volume by month. The adapter does not calculate YoY change in this tile."},"UsdaAmsRow8278":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.movement_lbs"],"properties":{"usda_region_pricing_movement.movement_lbs":{"type":["number","string","null"],"description":"SUM(total_volume), with an explicit fallback of 0 when missing. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"UsdaAmsTile8278":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"8278"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/UsdaAmsRow8278"}}},"required":["id","title","total","has_more","data"],"description":"Sum of movement in the window; when SUM is unavailable, the adapter uses zero."},"UsdaAmsRow8279":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.movement_lbs","usda_region_pricing_movement.pricing_origin"],"properties":{"usda_region_pricing_movement.movement_lbs":{"type":["number","string","null"],"description":"SUM(total_volume) for the aggregated rows. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"usda_region_pricing_movement.pricing_origin":{"type":["string","null"],"description":"Source origin. May be null when not reported.","examples":["Example origin"]}}},"UsdaAmsTile8279":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"8279"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/UsdaAmsRow8279"}}},"required":["id","title","total","has_more","data"],"description":"Legacy title; returns volume by origin, not news or posts."},"UsdaAmsRow8280":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.price","usda_region_pricing_movement.data_date","usda_region_pricing_movement.movement_lbs"],"properties":{"usda_region_pricing_movement.price":{"type":["number","string","null"],"description":"AVG(price_per_lb), excluding prices <= 0. Arithmetic mean, not weighted by volume. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"USD/lb","examples":[2.5],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"usda_region_pricing_movement.data_date":{"type":"string","description":"Source week_ending in YYYY-MM-DD format. Value serialized by the source CAST; YYYY-MM-DD is the example, but the underlying temporal type and format require validation against real BigQuery data.","examples":["2026-01-03"]},"usda_region_pricing_movement.movement_lbs":{"type":["number","string","null"],"description":"SUM(total_volume) for the aggregated rows. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"}}},"UsdaAmsTile8280":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"8280"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/UsdaAmsRow8280"}}},"required":["id","title","total","has_more","data"],"description":"Average price and aggregated volume by week_ending."},"UsdaAmsRow8281":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.data_week","usda_region_pricing_movement.movement_lbs"],"properties":{"usda_region_pricing_movement.data_week":{"type":"string","description":"Start of the week, Sunday, in YYYY-MM-DD format. Value serialized by the source CAST; YYYY-MM-DD is the example, but the underlying temporal type and format require validation against real BigQuery data.","examples":["2025-12-28"]},"usda_region_pricing_movement.movement_lbs":{"type":"object","additionalProperties":false,"required":["usda_region_pricing_movement.pricing_origin"],"properties":{"usda_region_pricing_movement.pricing_origin":{"type":"object","description":"Dynamic keys are origin names found in the source. A missing origin in a week or a zero sum results in null.","additionalProperties":{"type":["number","string","null"],"description":"NULLIF(SUM(total_volume),0), by origin and week. null indicates a missing measure or undefined calculation; it does not mean zero. The SDK returns FLOAT/INT64 as numbers and NUMERIC/BIGNUMERIC as decimal strings; the API does not force a conversion that loses precision.","x-unit":"lb","examples":[100],"pattern":"^-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$"},"examples":[{"Example origin":100}]}}}}},"UsdaAmsTile8281":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","const":"8281"},"title":{"type":"string","description":"Legacy or calculated title. See the dictionary for its meaning and formula."},"total":{"type":"integer","description":"Number of rows in this tile before pagination.","minimum":0},"has_more":{"type":"boolean","description":"This tile has rows beyond the current page."},"data":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/UsdaAmsRow8281"}}},"required":["id","title","total","has_more","data"],"description":"Pivot by week and origin. DATE_TRUNC(week_ending,WEEK) starts the week on Sunday in BigQuery."},"UsdaAmsSourceDashboard":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"usda-ams"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Filters echoed by the adapter using legacy names. They may differ from query names and omit base_size_filter; see the example and dictionary."},"fetched_at":{"type":"string","description":"API retrieval timestamp; the cache preserves it. This is not the source update time.","format":"date-time"},"timezone":{"type":"string","const":"UTC"},"page":{"type":"integer","description":"Requested page, applied independently to each tile.","minimum":1,"maximum":100},"page_size":{"type":"integer","description":"Maximum rows per tile on this page.","minimum":1,"maximum":100},"tiles":{"type":"array","minItems":8,"maxItems":8,"items":{"oneOf":[{"$ref":"#/components/schemas/UsdaAmsTile8274"},{"$ref":"#/components/schemas/UsdaAmsTile8275"},{"$ref":"#/components/schemas/UsdaAmsTile8276"},{"$ref":"#/components/schemas/UsdaAmsTile8277"},{"$ref":"#/components/schemas/UsdaAmsTile8278"},{"$ref":"#/components/schemas/UsdaAmsTile8279"},{"$ref":"#/components/schemas/UsdaAmsTile8280"},{"$ref":"#/components/schemas/UsdaAmsTile8281"}],"discriminator":{"propertyName":"id","mapping":{"8274":"#/components/schemas/UsdaAmsTile8274","8275":"#/components/schemas/UsdaAmsTile8275","8276":"#/components/schemas/UsdaAmsTile8276","8277":"#/components/schemas/UsdaAmsTile8277","8278":"#/components/schemas/UsdaAmsTile8278","8279":"#/components/schemas/UsdaAmsTile8279","8280":"#/components/schemas/UsdaAmsTile8280","8281":"#/components/schemas/UsdaAmsTile8281"}}}}},"required":["dashboard","filters","fetched_at","timezone","page","page_size","tiles"],"description":"Format produced by the adapters. Examples use synthetic data; real data has not yet been validated."},"UsdaAmsDemoDashboard":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"usda-ams"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Filters echoed by the adapter using legacy names. They may differ from query names and omit base_size_filter; see the example and dictionary."},"fetched_at":{"type":"string","description":"API retrieval timestamp; the cache preserves it. This is not the source update time.","format":"date-time"},"timezone":{"type":"string","const":"UTC"},"page":{"type":"integer","description":"Requested page, applied independently to each tile.","minimum":1,"maximum":100},"page_size":{"type":"integer","description":"Maximum rows per tile on this page.","minimum":1,"maximum":100},"demo":{"type":"boolean","const":true},"tiles":{"type":"array","minItems":1,"maxItems":1,"items":{"$ref":"#/components/schemas/DemoTile"}}},"required":["dashboard","filters","fetched_at","timezone","page","page_size","demo","tiles"],"description":"Response from the current demo provider. Its single generic tile does not represent real metrics."},"UsdaAmsDashboard":{"oneOf":[{"$ref":"#/components/schemas/UsdaAmsSourceDashboard"},{"$ref":"#/components/schemas/UsdaAmsDemoDashboard"}],"description":"Two explicitly separate formats: data adapter and demo. Do not mix tiles across modes."},"UsdaAmsFilterResponse":{"type":"object","additionalProperties":false,"properties":{"dashboard":{"type":"string","const":"usda-ams"},"filters":{"type":"array","items":{"$ref":"#/components/schemas/Filter"}},"demo":{"type":"boolean","const":true}},"required":["dashboard","filters"]}},"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Individual secret displayed once. Never use a query string. Does not authorize key management."},"PortalSession":{"type":"apiKey","in":"cookie","name":"portal_session","description":"Cookie obtained at login. Portal mutations also require Origin and X-CSRF-Token."}}},"x-policy":{"mode":{"data":"bigquery","identity":"glueup","glueup_ready":false,"production_ready":false,"description":"Real data, production grants, and production Glue Up login await validation. Examples are synthetic and never sourced from customers."},"limits":[{"name":"Key / test session","window_seconds":1,"units":20},{"name":"Key / test session","window_seconds":60,"units":120},{"name":"User","window_seconds":60,"units":240},{"name":"Organization","window_seconds":60,"units":1200},{"name":"IP (data budget)","window_seconds":60,"units":300},{"name":"IP (ingress, before authentication)","window_seconds":60,"requests":300},{"name":"Portal IP","window_seconds":60,"requests":300},{"name":"Login / IP","window_seconds":60,"requests":5},{"name":"Creation + rotation / account","window_seconds":3600,"requests":10}],"concurrency":{"user":4,"organization":16,"lease_seconds":60,"source_builds_per_process":4},"keys":{"active_per_account":5,"max_days":90,"default_days":90,"last_used_interval_seconds":300,"rotation_overlap_seconds":0,"revocation":"The next authentication started after commit, on any instance; requests already authenticated may finish.","organization":"Bound to the issuing organization. Changing organizations invalidates the old credential.","listing":"Up to 100 most recent records, ordered by created_at DESC and id DESC; no pagination in this version.","idempotency":"Creation/rotation POST is not idempotent and does not accept Idempotency-Key. After a timeout, list keys and confirm their state before retrying; secrets cannot be recovered."},"session":{"seconds":3600,"verification_seconds":900,"verification_status":"15 minutes in the development provider. Production revalidation is pending.","cookie":"portal_session; HttpOnly; SameSite=Strict; Secure in production; Path=/.","csrf":"Portal mutations require a cookie, exact Origin, and the current session's X-CSRF-Token. The token is returned at login and in the X-CSRF-Token header of GET /portal/session."},"abuse":{"violations":20,"window_seconds":600,"description":"The window starts at the first violation. Only the key's own budgets count toward blocking. Global and concurrency limits do not block an individual key.","recovery":"Owners cannot unblock keys; the protected administrative operation requires review and an audited reason. Revoked keys cannot be reactivated."},"cache":{"max_seconds":86400,"min_seconds":77760,"stale_while_revalidate":false,"lock_seconds":45,"wait_seconds":10,"description":"Authentication, authorization, and limits apply before every hit. Cache is partitioned by account, organization, and scopes. Errors and key management are not cached; no expired responses or infrastructure bypass.","invalidation":"TTL expiration with 90–100% jitter. Operational invalidation uses the dedicated cache Redis; no public invalidation endpoint exists."},"transport":{"body_max_bytes":8192,"cors_origin":"https://di-industry.blueberry.org","control_order":"The query is validated after authentication and controls. Parameter errors (400) and concurrency rejections may consume budget and update last use. Limit headers may appear on errors after admission.","request_id":"Generated by the API and returned in X-Request-ID; application-handled errors also include error.request_id. Network/TLS/proxy errors before the application may not use this envelope.","https":"Required in production; HTTP here is exclusively for the local demo."},"compatibility":{"version":"v1","notice_days":90,"description":"Breaking changes require v2. Proposed policy: at least 90 days' notice; no v1 sunset date is defined. New fields may be added; consumers must ignore unknown fields and identify tiles by ID, not position."},"pending":["Confirm the GlueUp mechanism and organization/tab permission matrix with Tom.","Validate schemas, real results, region, IAM, and SPINS/BigQuery redistribution licensing.","Identify the referenced Apify and post collections; the available code does not link them to the four tabs.","Configure and validate the production domain, Cloudflare, retention, failover, and backup restoration."]},"x-error-catalog":[{"status":400,"code":"invalid_request","description":"Invalid parameter, JSON body, format, or combination.","recovery":"Review the specification; unknown and repeated parameters are rejected."},{"status":400,"code":"credentials_in_query","description":"Credential submitted in a URL parameter.","recovery":"Use the X-API-Key header; never send secrets in URLs."},{"status":401,"code":"unauthorized","description":"Missing/invalid credential, expired/revoked/blocked key, changed organization, inactive account, or expired verification.","recovery":"Check the account and issue a new credential if needed; do not retry indefinitely."},{"status":403,"code":"scope_forbidden","description":"The key and account do not have the required scope.","recovery":"Request the appropriate grant; a key does not expand account permissions."},{"status":403,"code":"csrf_failed","description":"Invalid Origin or CSRF token in a portal mutation.","recovery":"Sign in to the portal again and use the current session's CSRF token."},{"status":403,"code":"origin_forbidden","description":"Login Origin differs from the configured origin.","recovery":"Use the portal at the origin listed in servers; browsers send Origin automatically."},{"status":404,"code":"not_found","description":"Route not found.","recovery":"Check the endpoint version and path."},{"status":404,"code":"key_not_found","description":"The key does not belong to the account, does not exist, or cannot be rotated.","recovery":"Check the ID; rotation requires an active, unexpired key."},{"status":409,"code":"active_key_limit","description":"Maximum number of active keys reached.","recovery":"Revoke a key or rotate an existing one."},{"status":409,"code":"key_revoked","description":"Attempt to reactivate a revoked key.","recovery":"Issue a new key; revocation is permanent."},{"status":413,"code":"internal_error","description":"Body exceeds the 8192-byte limit; HTTP error normalized by the current handler.","recovery":"Reduce the body size. This error's message is Request rejected."},{"status":415,"code":"internal_error","description":"Content-Type not accepted by the parser; HTTP error normalized by the current handler.","recovery":"Use application/json for bodies; omit Content-Type on bodyless DELETE/logout requests."},{"status":429,"code":"rate_limit","description":"Key, user, organization, or IP budget exhausted.","recovery":"Honor Retry-After. Repeated violations of the key's own budgets may cause blocking."},{"status":429,"code":"concurrency_limit","description":"User or organization concurrency exhausted.","recovery":"Honor Retry-After and reduce concurrent requests; the budget may already have been consumed."},{"status":429,"code":"key_creation_limit","description":"Shared creation and rotation limit exceeded.","recovery":"Wait for Retry-After before creating or rotating again."},{"status":500,"code":"internal_error","description":"Unexpected internal error or persistence failure.","recovery":"Provide X-Request-ID to support. Before retrying a mutation, check the state to avoid duplicates."},{"status":501,"code":"glueup_pending_confirmation","description":"Glue Up sign-in is disabled for this configuration.","recovery":"Check GET /auth/status. The Glue Up flow and grants await approval."},{"status":503,"code":"security_unavailable","description":"Security Redis is unavailable or cannot enforce limits.","recovery":"The API denies access until controls recover; use bounded retries with backoff."},{"status":503,"code":"cache_unavailable","description":"Shared cache/lock unavailable, including writes after querying the source.","recovery":"Retry with bounded backoff; there is no cache bypass."},{"status":503,"code":"source_busy","description":"Build limit reached or the wait of up to 10 seconds for an in-progress cache miss expired.","recovery":"Reduce concurrency and retry with bounded backoff."},{"status":503,"code":"source_unavailable","description":"The source query failed or exceeded its limits.","recovery":"Use bounded backoff; report the request ID if the issue persists."}],"x-dashboards":{"retail":{"label":"Retail SPINS","scope":"dashboard:retail","description":"SPINS metrics by product, size, geography, and growing method.","cadence":"Source interface description: monthly. No confirmed update SLA; fetched_at is not the source update time.","notes":["Periods 28/84/182/365 map to 4/12/26/52 Weeks in the aggregate table. Trends use 28/84/182/364 days aligned to Saturday.","Shares always use lb. YoY for Units also uses lb. Units is estimated by dividing by the numeric size, as in the original SQL.","fresh_frozen affects size comparisons and weekly series; Fresh and Frozen KPIs continue to return their categories separately.","base_size_filter is applied by SQL but is not echoed in appliedFilters by the original adapter.","Measures may be numbers or decimal strings depending on the underlying BigQuery type (the SDK preserves NUMERIC/BIGNUMERIC precision). The actual source schema still requires validation; examples use synthetic values."],"tiles":[{"id":"6287","title":"Total LB (Fresh)","description":"Total of the selected metric for Fresh.","rowSchema":{"$ref":"#/components/schemas/RetailRow6287"}},{"id":"6289","title":"Total LB (Frozen)","description":"Total of the selected metric for Frozen.","rowSchema":{"$ref":"#/components/schemas/RetailRow6289"}},{"id":"6292","title":"% of Total LB (Fresh)","description":"Fresh share of total volume in lb. The formula uses lb even when Dollars or Units is selected.","rowSchema":{"$ref":"#/components/schemas/RetailRow6292"}},{"id":"6293","title":"LB % Change YoY (Fresh)","description":"Fresh year-over-year change: 100 × (current − previous) / previous. Uses dollars for Dollars and lb for LB and Units.","rowSchema":{"$ref":"#/components/schemas/RetailRow6293"}},{"id":"6294","title":"LB % Change YoY (Frozen)","description":"Frozen year-over-year change: 100 × (current − previous) / previous. Uses dollars for Dollars and lb for LB and Units.","rowSchema":{"$ref":"#/components/schemas/RetailRow6294"}},{"id":"6295","title":"% of Total LB (Frozen)","description":"Frozen share of total volume in lb. The formula uses lb even when Dollars or Units is selected.","rowSchema":{"$ref":"#/components/schemas/RetailRow6295"}},{"id":"6298","title":"Product Size Comparison","description":"Aggregated by size. Units is estimated as total_lbs / the number extracted from base_size; the adapter performs no additional oz/lb conversion.","rowSchema":{"$ref":"#/components/schemas/RetailRow6298"}},{"id":"6299","title":"Pricing Trend $/lb","description":"Weekly series of volume-weighted prices; window aligned to Saturday.","rowSchema":{"$ref":"#/components/schemas/RetailRow6299"}},{"id":"6300","title":"Untitled","description":"Maximum and minimum dates in the selected weekly series; the legacy title is preserved.","rowSchema":{"$ref":"#/components/schemas/RetailRow6300"}},{"id":"6302","title":"Total Trend","description":"Weekly series of the selected metric. The previous measure uses _ya fields.","rowSchema":{"$ref":"#/components/schemas/RetailRow6302"}}],"schema":"RetailDashboard"},"imports":{"label":"USDA Imports","scope":"dashboard:imports","description":"Pre-aggregated import volumes by country, HS code, and berry category.","cadence":"Source interface description: weekly. The queried table contains monthly aggregates; no confirmed SLA.","notes":["Accepts only 365 days. This value represents the pre-aggregated current period, not an exact 365-day rolling window.","DAY(week_ending)=1 identifies current rows; other rows provide pounds_ya for comparison.","Percentage changes are ratios: 0.25 = 25%, unlike Retail's percentage fields.","Measures may be numbers or decimal strings depending on the underlying BigQuery type (the SDK preserves NUMERIC/BIGNUMERIC precision). The actual source schema still requires validation; examples use synthetic values."],"tiles":[{"id":"1258","title":"Berry Imports by Country","description":"Current volume by country and berry category. Rows for the first day of the month in the pre-aggregated table.","rowSchema":{"$ref":"#/components/schemas/ImportsRow1258"}},{"id":"1259","title":"Map by Source Country","description":"Total current volume by country.","rowSchema":{"$ref":"#/components/schemas/ImportsRow1259"}},{"id":"1261","title":"Import Volume by Berry","description":"Comparison by HS code: current uses DAY=1 rows; previous uses pounds_ya from other rows.","rowSchema":{"$ref":"#/components/schemas/ImportsRow1261"}},{"id":"1262","title":"Monthly Imports by Berry Type","description":"Current monthly volume by berry category.","rowSchema":{"$ref":"#/components/schemas/ImportsRow1262"}},{"id":"1263","title":"Imports by Berry Type","description":"Monthly pivot by HS code and category. Nested structure; not a scalar measure.","rowSchema":{"$ref":"#/components/schemas/ImportsRow1263"}},{"id":"1265","title":"Untitled","description":"Latest available current date, preserving the legacy title.","rowSchema":{"$ref":"#/components/schemas/ImportsRow1265"}}],"schema":"ImportsDashboard"},"exports":{"label":"USDA FAS Exports","scope":"dashboard:exports","description":"Exports (flow_type Export) by country, month, and berry category.","cadence":"Source interface description: monthly; no confirmed SLA.","notes":["Nominal window aligned to Saturday from CURRENT_DATE UTC; SQL does not exclude potential future source dates.","The titles “avg”, “Top”, and “Untitled” are legacy labels: see the documented formula; do not infer an average or top N from the title.","Changes are ratios: 0.25 = +25%.","Measures may be numbers or decimal strings depending on the underlying BigQuery type (the SDK preserves NUMERIC/BIGNUMERIC precision). The actual source schema still requires validation; examples use synthetic values."],"tiles":[{"id":"1301","title":"Blueberry Exports by Time","description":"Monthly export volume (flow_type Export) by berry category.","rowSchema":{"$ref":"#/components/schemas/ExportsRow1301"}},{"id":"1302","title":"Exports by Country","description":"Export volume by country.","rowSchema":{"$ref":"#/components/schemas/ExportsRow1302"}},{"id":"1303","title":"Exports by Month (avg)","description":"Despite “avg” in the legacy title, SQL calculates SUM, not an average.","rowSchema":{"$ref":"#/components/schemas/ExportsRow1303"}},{"id":"1304","title":"Untitled","description":"Same country projection as tile 1302, preserved from the adapter.","rowSchema":{"$ref":"#/components/schemas/ExportsRow1304"}},{"id":"1305","title":"Top Export Countries","description":"Source aggregation by country. SQL does not apply LIMIT; this is not a top N list. The API sorts lexicographically for pagination.","rowSchema":{"$ref":"#/components/schemas/ExportsRow1305"}}],"schema":"ExportsDashboard"},"usda-ams":{"label":"USDA AMS","scope":"dashboard:usda-ams","description":"FOB prices and movement in lb, aggregated by period and origin.","cadence":"Source interface description: daily; no confirmed SLA.","notes":["Nominal window aligned to Saturday from CURRENT_DATE UTC; SQL has no explicit upper bound.","Titles containing YoY return monthly series; the adapter does not calculate the change.","USDA Market News returns volumes by origin. This tile contains no news, posts, or Apify collection.","Prices are arithmetic means of positive values; they are not weighted by volume.","Measures may be numbers or decimal strings depending on the underlying BigQuery type (the SDK preserves NUMERIC/BIGNUMERIC precision). The actual source schema still requires validation; examples use synthetic values."],"tiles":[{"id":"8274","title":"Average FOB Price/Lb","description":"Arithmetic mean FOB price in the nominal window aligned to Saturday.","rowSchema":{"$ref":"#/components/schemas/UsdaAmsRow8274"}},{"id":"8275","title":"Date As Of","description":"Distinct dates in the window. Not just one row containing the latest date.","rowSchema":{"$ref":"#/components/schemas/UsdaAmsRow8275"}},{"id":"8276","title":"FOB Change YoY","description":"Legacy title; returns average price by month. The adapter does not calculate YoY change in this tile.","rowSchema":{"$ref":"#/components/schemas/UsdaAmsRow8276"}},{"id":"8277","title":"Movement (Lbs) Change YoY","description":"Legacy title; returns summed volume by month. The adapter does not calculate YoY change in this tile.","rowSchema":{"$ref":"#/components/schemas/UsdaAmsRow8277"}},{"id":"8278","title":"Total Movement Current KPI","description":"Sum of movement in the window; when SUM is unavailable, the adapter uses zero.","rowSchema":{"$ref":"#/components/schemas/UsdaAmsRow8278"}},{"id":"8279","title":"USDA Market News","description":"Legacy title; returns volume by origin, not news or posts.","rowSchema":{"$ref":"#/components/schemas/UsdaAmsRow8279"}},{"id":"8280","title":"USDA Movement and Pricing by Week","description":"Average price and aggregated volume by week_ending.","rowSchema":{"$ref":"#/components/schemas/UsdaAmsRow8280"}},{"id":"8281","title":"Weekly Movement by Region","description":"Pivot by week and origin. DATE_TRUNC(week_ending,WEEK) starts the week on Sunday in BigQuery.","rowSchema":{"$ref":"#/components/schemas/UsdaAmsRow8281"}}],"schema":"UsdaAmsDashboard"}}}