Answers to the questions integrators most commonly hit against the Titan Public API.
The API uses OAuth 2.0 client credentials. Create a CLIENT_ID / CLIENT_SECRET pair from Connectors → APIs in the SecurityScorecard app, then exchange them at POST /v1/oauth/token with grant_type=client_credentials. Full walkthrough in Getting Started.
The same credentials work for both REST and MCP.
401 means the request was not authenticated. Common causes:
- No
Authorization: Bearer …header on the request. - The bearer token is malformed (extra whitespace, missing
Bearerprefix, or the header holds the rawCLIENT_SECRETinstead of an access token). - The access token has expired — re-exchange your
CLIENT_ID/CLIENT_SECRET. - The credential has been deleted or rotated. Confirm it still exists on the Connectors → APIs page.
403 means the token was valid but the caller is not permitted. Common causes:
- The credential lacks the required scope. Read-only calls need Read security findings; mutating calls additionally need Flag security findings. Scopes are set when the credential is created — issue a new credential with the right scopes.
- The token's
orgclaim doesn't match the resource. Every credential is scoped to the organization that issued it.
Honour the Retry-After header — it tells you how many seconds to wait before retrying. If unavailable, fall back to exponential backoff with jitter (base 1s, factor 2, cap 60s).
Do not retry immediately, and do not rotate credentials or IPs to evade the limit — the counter is keyed by organization. See Usage Limits.
The limits are numerically identical but the counters are independent — a burst on REST won't starve MCP or vice versa.
Contact your SecurityScorecard account team with your organization identifier, the endpoints you'll call, and whether traffic is steady or bursty. See Usage Limits.
Flag actions are idempotent by design. A 409 conflict means the resource is in a state that rejects the operation — for example, flagging something already resolved. Do not blindly retry a 409. Read error.code and either adjust the request or treat the current state as the accepted outcome. See Errors.
Interactive AI clients don't always auto-invoke MCP tools from a generic prompt. Reliable fixes:
- Name the tool explicitly: "Use
GetObservationsto list this week's CVE findings." - Name the connector: "Using the Titan MCP connector, show me high-severity findings."
- Ask the client to list tools first: "List the tools available from the Titan MCP server, then answer …"
See MCP → Prompting.
Same causes as REST 401 above. MCP uses the same bearer token as REST.
The credential lacks the scope for the tool you invoked. See MCP → Scopes.
- The credential's
orgmust match the organization whose data you expect — cross-org calls always return empty. - Confirm the tool actually ran by asking the client to show its tool-call trace.
Cursor mode: next_cursor is absent or empty. A short page is not a reliable end-of-stream signal — always check next_cursor.
Offset mode: the response contains zero rows.
See Pagination.
Cursors expire after ~24 hours. Restart from cursor="" and dedupe by resource id.
No — give each worker a disjoint filter (e.g. a distinct time range) instead. See Pagination.
Include error.request_id from the failing response — without it we cannot correlate your call to server logs. Full checklist in Errors → Reporting a bug.