Appearance
Troubleshooting: 404 Not Found (Anti-Enumeration)
Some org-scoped services intentionally return 404 not-found when the caller is not associated with the org, even if the org or record exists. This hides tenant existence from unrelated callers (anti-enumeration). A 404 can therefore mean either "doesn't exist" or "you aren't allowed to know it exists."
This page helps you tell those cases apart.
WAF 403 (no JSON body)
If you receive a 403 response with an HTML body (not JSON), the request was blocked by the Web Application Firewall before reaching the application. Common causes:
- Request body contains patterns matching known attack signatures (SQL fragments,
<script>tags,${jndi:...},../path traversal). - Source IP is on the AWS IP Reputation blocklist.
- Source IP exceeded 2,000 requests in 5 minutes (WAF rate limit).
Resolution: Inspect your request payload for suspicious patterns. Free-text fields (product descriptions, comments) with HTML-like content can trigger the Common Rule Set. If you believe it's a false positive, contact support with the request timestamp and source IP.
How to tell WAF 403 from app 403: Application 403 always has a JSON body with error.major.tag. WAF 403 has an HTML body and no error object.
Quick checklist
- Use the custom domain:
https://api.g3nretailstack.com/<service>/...(avoid execute-api URLs). - Confirm auth is valid: session is active (or API key is active) and sent in the correct place (headers for GET; JSON body for POST unless the service says otherwise).
- Confirm org association: the session or API key must belong to the org you're querying.
- Confirm orgcode: typos in
orgcodeare the most common 404 cause. - Confirm ID vs code: many endpoints accept either
*_idorcode. Passing a code where an ID is required returns 404. - GET semantics: GET parameters go in the query string. JSON bodies are ignored on GET.
- Treat 404 as ambiguous: it can mean not found or not associated. Run the self-check flow before assuming absence.
Copy-paste checks
1) Validate your credential (401 vs 404)
Session (human)
sh
curl -sS -X POST https://api.g3nretailstack.com/usm/session/validate \
-H 'Content-Type: application/json' \
-d '{"session_guid":"SESSION_GUID","reason":"debug"}'- 401 means the session is invalid/expired/suspended.
- 200 means the session is valid; move on to org association.
API key (service account)
sh
curl -sS -X POST https://api.g3nretailstack.com/usm/api_key/validate \
-H 'Content-Type: application/json' \
-H 'x-api-key: API_KEY' \
-d '{"actor":"debug","reason":"debug"}'- 401 means the API key is invalid/expired/revoked.
- 200 means the API key is valid; move on to org association.
2) Confirm org association (anti-enumeration check)
Session (human)
sh
curl -sS -X POST https://api.g3nretailstack.com/ofm/member/resolve \
-H 'Content-Type: application/json' \
-H 'x-session-guid: SESSION_GUID' \
-d '{"orgcode":"ORGCODE"}'- 200 means the session is associated (owner or member) and returns roles.
- 404 not-found means you are not associated with that org (anti-enumeration).
API key (service account)
sh
curl -sS -X POST https://api.g3nretailstack.com/ofm/member/resolve \
-H 'Content-Type: application/json' \
-H 'x-api-key: API_KEY' \
-d '{"orgcode":"ORGCODE"}'- 200 means the API key is associated (owner or role-bearing service account).
- 404 not-found means you are not associated with that org (anti-enumeration).
3) Confirm org status for writes (403 org-write-blocked)
Many writes require org.status=verified. If writes fail with 403 (org-write-blocked), the org must be verified by an operator.
Interpreting 401 vs 403 vs 404
- 401 Unauthorized: session invalid/expired or API key invalid/expired.
- 403 Forbidden: you are associated but lack the required role, or the org is in a write-blocked status.
- 404 Not Found: resource truly missing or you are not associated (anti-enumeration).
Service-level anti-enumeration matrix (current)
| Service | Non-associated caller | Notes |
|---|---|---|
| UAS | 401 on invalid credentials | /uas/stat hides existence by design. |
| USM | 401/403 | Session/API-key validation failures are 401. |
| OFM | 404 | Org-scoped operations return 404 when not associated. |
| MRS | 404 | Org-scoped records are hidden for non-associated callers. |
| PVM | 404 | Org-scoped product records are hidden for non-associated callers. |
| PMC | 404 | Published product records are hidden for non-associated callers. |
| ICS | 404 | Inventory records are hidden for non-associated callers. |
| SCM | 404 | Orders and fulfillment records are hidden for non-associated callers. |
| PCM | 404 | Procurement records are hidden for non-associated callers. |
| PPM | 404 | Pricing/promotion records are hidden for non-associated callers. |
| CRM | 404 | Customer records are hidden for non-associated callers. |
| Influencer | 404 | Attribution/earnings records are hidden for non-associated callers. |
| Accounting | 404 | Financial exports are hidden for non-associated callers. |
| IPM | 404 | Integration plane resources are hidden for non-associated callers. |
| RBS | 404 | Subscriptions are hidden for non-associated callers. |
| UTL | 404 | Offboarding/export resources are hidden for non-associated callers. |
| OPS | Root-only | All operations require root auth (scrypt secret). No session-based access. |
| UCP | 404 | Triple auth model (admin/platform/bearer). Non-associated callers see 404. |
| SLC | 404 | Action-dispatch model. Org-scoped channels hidden for non-associated callers. |
| VisualGrid | Root-only | All operations require root auth (scrypt secret). No session-based access. |
If a service behaves differently, it will document the exception on its Surfaces page.
Common 404 causes (beyond anti-enumeration)
- Wrong resource type:
style_idvsvariant_id,org_guidvsorgcode. - Wrong channel selector: missing
channel_guid/channel_codein PMC queries. - Wrong status: some list endpoints default to
status=activeand hide inactive/doomed records. - Typos in codes: codes are case-sensitive in most places; check canonicalization rules on each service page.
When you need to prove existence
Use an owner session for the org or an operator-only direct Lambda (where applicable). Owner sessions can disambiguate "not found" vs "not associated."
See also:
- /common/role-matrix.html for role expectations.
- /common/minimum-viable-flow.html for a known-good end-to-end flow.