# Troubleshooting Empty Responses This guide helps you diagnose cases where a GET request succeeds with 200 OK but the response body is an empty array (`[]`) when retrieving objects (e.g., vendors, controls, risks, tasks) via the Hyperproof API. ## Who this is for * Integrators using service accounts. * Developers calling object collection endpoints such as `GET /v1/vendors`, `GET /v1/controls`, `GET /v1/risks`, etc. ## Common symptom Example response (200 + empty body): ```json { "get_hyperproof_objects": { "body": [], "status": 200 } } ``` A 200 indicates the request was valid and authorized, but no objects were returned. The most common reason is insufficient role or object‑level permissions for the principal (often a service account), even if the OAuth scope appears correct. ## Why this happens Even with a valid service account and an OAuth client including the correct read scope (e.g., `vendor.read`, `control.read`, `risk.read`), the API may return an empty array if: * The principal lacks a suitable role (e.g., not an API Admin) and * The principal does not appear on the object register’s explicit access list (often called the facepile) for that object type. > In Hyperproof, some object types (e.g., vendors) require explicit access in addition to scopes. This behavior is intentional and protects object-level data. ## Step-by-step resolution ### Confirm role assignment * Check whether the service account has a role that confers the needed visibility (e.g., API Admin). * If not, either: * Assign the API Admin role to the service account, or * Add the service account to the object register access list (facepile) for the relevant object type(s) in the UI. Example (assign role via API): ```http POST /api/organizations/:orgId/users/roles Content-Type: application/json { "roleId": "", "principalId": "", "principalType": "User" } ``` > Use least privilege when possible: prefer targeted access list membership if full admin is not required. ### Verify OAuth scope(s) * Ensure the OAuth client includes the read scope for the target object type: * Vendors → `vendor.read` * Controls → `control.read` * Risks → `risk.read` * (and so on for other objects) Quick scope check (example vendors): ```bash curl --request GET \ --url "https://api.hyperproof.app/v1/vendors" \ --header "Authorization: Bearer $ACCESS_TOKEN" ``` If the token lacks the necessary scope, the response may be empty or otherwise constrained. ### Re‑authenticate after permissions change * After changing roles or access lists, mint a new access token and retry the request. * Permission changes do not retroactively affect existing tokens. ```bash # Mint a fresh token (method depends on your OAuth flow) # Then retry curl --request GET \ --url "https://api.hyperproof.app/v1/vendors" \ --header "Authorization: Bearer $NEW_ACCESS_TOKEN" ``` ### Check data existence and filters * Confirm that objects actually exist under the organization in question. * Review any query parameters (filters, pagination) that could narrow the result set to zero. Examples: ```bash # No filters: list all vendors visible to the principal curl -sS -H "Authorization: Bearer $ACCESS_TOKEN" \ "https://api.hyperproof.app/v1/vendors" # Controls example with a filter that might be too restrictive curl -sS -H "Authorization: Bearer $ACCESS_TOKEN" \ "https://api.hyperproof.app/v1/controls?status=archived" # Try removing or adjusting filters if you get [] ``` ### Validate organization / environment * Double‑check you are calling the intended tenant/org and environment (e.g., production vs. staging). A valid token for a different org with no data will yield `[]`. ### Object‑level access (facepile) * For object types that enforce explicit access (e.g., vendors), add the service account to the register’s access list in the UI if you choose not to grant a broad admin role. * After updating access, re‑authenticate (Step 3). ## Quick diagnostic checklist * [ ] Token minted after the latest permission changes * [ ] OAuth client includes the correct read scope for the object type * [ ] Service account has a suitable role *or* appears on the object access list (facepile) * [ ] You are querying the correct org/environment * [ ] Request does not include overly restrictive filters * [ ] There are objects to return ## Expected behavior after resolution Once the principal has: * Appropriate role or explicit object access, and * The necessary read scope(s), collection endpoints will return the visible objects instead of an empty array. Examples: ```bash # Vendors curl -sS -H "Authorization: Bearer $ACCESS_TOKEN" \ "https://api.hyperproof.app/v1/vendors" # Controls curl -sS -H "Authorization: Bearer $ACCESS_TOKEN" \ "https://api.hyperproof.app/v1/controls" # Risks curl -sS -H "Authorization: Bearer $ACCESS_TOKEN" \ "https://api.hyperproof.app/v1/risks" ``` ## Notes * Scopes control what a token is allowed to do; roles and access lists control what a principal is allowed to see. You typically need both. * Prefer least privilege: grant narrow, explicit access where possible. * Some endpoints (e.g., metadata or helpers) may behave differently; consult the official developer portal for details on each object API.