{"info":{"name":"Blueberries Public API v1","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json","description":"Set api_key for dashboards. For portal operations, sign in using the Postman cookie jar and copy the CSRF token into csrf_token. Set key_id from the key list when rotating or revoking. Keep populated credentials local."},"variable":[{"key":"base_url","value":"http://di-industry.blueberry.org"},{"key":"api_key","value":""},{"key":"portal_email","value":""},{"key":"portal_password","value":""},{"key":"csrf_token","value":""},{"key":"key_id","value":""}],"item":[{"name":"Retail SPINS","item":[{"name":"Get Retail SPINS","request":{"method":"GET","header":[{"key":"X-API-Key","value":"{{api_key}}"}],"url":{"raw":"{{base_url}}/v1/dashboards/retail","host":["{{base_url}}"],"path":["v1","dashboards","retail"],"query":[{"key":"period","value":"365 days","description":"Nominal period. Retail uses 4/12/26/52 Weeks; series are aligned to Saturday.","disabled":true},{"key":"page","value":"1","description":"Page per tile; a page past the end returns empty data, not 404.","disabled":true},{"key":"page_size","value":"50","description":"Up to 100 rows per tile, not per response.","disabled":true},{"key":"spins_all_iq.geography_region_filter","value":"TOTAL US - MULO","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.","disabled":true},{"key":"spins_all_iq.geography_type","value":"US Total","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.","disabled":true},{"key":"spins_all_iq.labeled_organic","value":"CONVENTIONAL,ORGANIC","description":"Growing methods. The accepted combined order is CONVENTIONAL,ORGANIC; this combination is the default. Single query value; do not repeat the parameter.","disabled":true},{"key":"spins_all_iq.base_size_filter","value":"6 oz","description":"Up to ten comma-separated sizes; the adapter trims values and removes empty entries. Single query value; do not repeat the parameter.","disabled":true},{"key":"spins_all_iq.measure_filter","value":"LB","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.","disabled":true},{"key":"spins_all_iq.fresh_frozen","value":"Fresh","description":"Affects size comparisons and weekly series; does not remove the separate Fresh/Frozen KPIs. Single query value; do not repeat the parameter.","disabled":true}]},"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."}},{"name":"List filters for Retail SPINS","request":{"method":"GET","header":[{"key":"X-API-Key","value":"{{api_key}}"}],"url":{"raw":"{{base_url}}/v1/dashboards/retail/filters","host":["{{base_url}}"],"path":["v1","dashboards","retail","filters"]},"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."}}]},{"name":"USDA Imports","item":[{"name":"Get USDA Imports","request":{"method":"GET","header":[{"key":"X-API-Key","value":"{{api_key}}"}],"url":{"raw":"{{base_url}}/v1/dashboards/imports","host":["{{base_url}}"],"path":["v1","dashboards","imports"],"query":[{"key":"period","value":"365 days","description":"Pre-aggregated current period; other values are rejected. This is not a rolling window.","disabled":true},{"key":"page","value":"1","description":"Page per tile; a page past the end returns empty data, not 404.","disabled":true},{"key":"page_size","value":"50","description":"Up to 100 rows per tile, not per response.","disabled":true}]},"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."}},{"name":"List filters for USDA Imports","request":{"method":"GET","header":[{"key":"X-API-Key","value":"{{api_key}}"}],"url":{"raw":"{{base_url}}/v1/dashboards/imports/filters","host":["{{base_url}}"],"path":["v1","dashboards","imports","filters"]},"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."}}]},{"name":"USDA FAS Exports","item":[{"name":"Get USDA FAS Exports","request":{"method":"GET","header":[{"key":"X-API-Key","value":"{{api_key}}"}],"url":{"raw":"{{base_url}}/v1/dashboards/exports","host":["{{base_url}}"],"path":["v1","dashboards","exports"],"query":[{"key":"period","value":"365 days","description":"Nominal period. Retail uses 4/12/26/52 Weeks; series are aligned to Saturday.","disabled":true},{"key":"page","value":"1","description":"Page per tile; a page past the end returns empty data, not 404.","disabled":true},{"key":"page_size","value":"50","description":"Up to 100 rows per tile, not per response.","disabled":true}]},"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."}},{"name":"List filters for USDA FAS Exports","request":{"method":"GET","header":[{"key":"X-API-Key","value":"{{api_key}}"}],"url":{"raw":"{{base_url}}/v1/dashboards/exports/filters","host":["{{base_url}}"],"path":["v1","dashboards","exports","filters"]},"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."}}]},{"name":"USDA AMS","item":[{"name":"Get USDA AMS","request":{"method":"GET","header":[{"key":"X-API-Key","value":"{{api_key}}"}],"url":{"raw":"{{base_url}}/v1/dashboards/usda-ams","host":["{{base_url}}"],"path":["v1","dashboards","usda-ams"],"query":[{"key":"period","value":"365 days","description":"Nominal period. Retail uses 4/12/26/52 Weeks; series are aligned to Saturday.","disabled":true},{"key":"page","value":"1","description":"Page per tile; a page past the end returns empty data, not 404.","disabled":true},{"key":"page_size","value":"50","description":"Up to 100 rows per tile, not per response.","disabled":true}]},"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."}},{"name":"List filters for USDA AMS","request":{"method":"GET","header":[{"key":"X-API-Key","value":"{{api_key}}"}],"url":{"raw":"{{base_url}}/v1/dashboards/usda-ams/filters","host":["{{base_url}}"],"path":["v1","dashboards","usda-ams","filters"]},"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."}}]},{"name":"Authentication","item":[{"name":"Check login availability","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/auth/status","host":["{{base_url}}"],"path":["auth","status"]},"description":"Reports the configured identity provider, whether its login flow is enabled, and whether data are synthetic. Availability reflects configuration."}},{"name":"Sign in to the developer portal","request":{"method":"POST","header":[{"key":"Origin","value":"{{base_url}}"},{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{base_url}}/auth/login","host":["{{base_url}}"],"path":["auth","login"]},"body":{"mode":"raw","raw":"{\n  \"email\": \"{{portal_email}}\",\n  \"password\": \"{{portal_password}}\"\n}","options":{"raw":{"language":"json"}}},"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."}},{"name":"Sign out of the developer portal","request":{"method":"POST","header":[{"key":"Origin","value":"{{base_url}}"},{"key":"X-CSRF-Token","value":"{{csrf_token}}"}],"url":{"raw":"{{base_url}}/auth/logout","host":["{{base_url}}"],"path":["auth","logout"]},"description":"Deletes the current session and clears the session cookie. Send an empty request without Content-Type."}}]},{"name":"Account portal","item":[{"name":"Resume a portal session","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/portal/session","host":["{{base_url}}"],"path":["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."}},{"name":"Read your profile","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/portal/profile","host":["{{base_url}}"],"path":["portal","profile"]},"description":"Returns the email and display name of the account associated with the portal session."}},{"name":"Update your display name","request":{"method":"PATCH","header":[{"key":"Origin","value":"{{base_url}}"},{"key":"X-CSRF-Token","value":"{{csrf_token}}"},{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{base_url}}/portal/profile","host":["{{base_url}}"],"path":["portal","profile"]},"body":{"mode":"raw","raw":"{\n  \"display_name\": \"Example Developer\"\n}","options":{"raw":{"language":"json"}}},"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."}},{"name":"List your API keys","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/portal/keys","host":["{{base_url}}"],"path":["portal","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."}},{"name":"Create an API key","request":{"method":"POST","header":[{"key":"Origin","value":"{{base_url}}"},{"key":"X-CSRF-Token","value":"{{csrf_token}}"},{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{base_url}}/portal/keys","host":["{{base_url}}"],"path":["portal","keys"]},"body":{"mode":"raw","raw":"{\n  \"name\": \"Imports integration\",\n  \"scopes\": [\n    \"dashboard:imports\"\n  ],\n  \"days\": 1\n}","options":{"raw":{"language":"json"}}},"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."}},{"name":"Rotate an API key","request":{"method":"POST","header":[{"key":"Origin","value":"{{base_url}}"},{"key":"X-CSRF-Token","value":"{{csrf_token}}"},{"key":"Content-Type","value":"application/json"}],"url":{"raw":"{{base_url}}/portal/keys/{{key_id}}/rotate","host":["{{base_url}}"],"path":["portal","keys","{{key_id}}","rotate"]},"body":{"mode":"raw","raw":"{\n  \"name\": \"Imports integration\",\n  \"scopes\": [\n    \"dashboard:imports\"\n  ],\n  \"days\": 1\n}","options":{"raw":{"language":"json"}}},"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."}},{"name":"Revoke an API key","request":{"method":"DELETE","header":[{"key":"Origin","value":"{{base_url}}"},{"key":"X-CSRF-Token","value":"{{csrf_token}}"}],"url":{"raw":"{{base_url}}/portal/keys/{{key_id}}","host":["{{base_url}}"],"path":["portal","keys","{{key_id}}"]},"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."}}]},{"name":"Health","item":[{"name":"Check liveness","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/health/live","host":["{{base_url}}"],"path":["health","live"]},"description":"Checks that the HTTP process responds."}},{"name":"Check readiness","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/health/ready","host":["{{base_url}}"],"path":["health","ready"]},"description":"Checks the PostgreSQL migrations table and both Redis connections. It does not query the dashboard data source."}}]},{"name":"Documentation","item":[{"name":"Get the public OpenAPI specification","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/openapi.json","host":["{{base_url}}"],"path":["openapi.json"],"query":[{"key":"download","value":"1","description":"Set to 1 to download the same document as an attachment.","disabled":true}]},"description":"OpenAPI 3.1.1 document for the current installation, with a same-origin server URL."}},{"name":"Get the Postman collection","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/postman.collection.json","host":["{{base_url}}"],"path":["postman.collection.json"],"query":[{"key":"download","value":"1","description":"Set to 1 to download the same document as an attachment.","disabled":true}]},"description":"Postman 2.1 collection for the current installation, with empty credential variables."}},{"name":"Get the data dictionary","request":{"method":"GET","header":[],"url":{"raw":"{{base_url}}/data-dictionary.json","host":["{{base_url}}"],"path":["data-dictionary.json"],"query":[{"key":"download","value":"1","description":"Set to 1 to download the same document as an attachment.","disabled":true}]},"description":"Dashboard definitions keyed by dashboard slug, including tile IDs, field schemas, and calculation notes."}}]}]}