Errors
Introduction
A failed request returns an HTTP status of 400 or above and a JSON body with an error object. Branch on error.code, not on the HTTP status alone: two 403s or two 429s can mean different things.
{
"error": {
"code": "BAD_REQUEST",
"message": "Invalid request",
"details": {
"errors": [
"unknown target_verticals value \"Pharmaceuticals\"; did you mean \"Biopharmaceuticals\"?",
"limit must be <= 1000"
]
}
}
}| field | type | description |
|---|---|---|
error.code | string | Machine-readable code from the table below. |
error.message | string | Human-readable summary. |
error.details | object | Present on some errors. Validation errors list every problem in details.errors, so you can fix them all at once. Trial-key refusals list the refused ids in details.ids. |
A failed request is never charged against the monthly record quota, and it returns no data.
Error codes
| Status | Code | When | What to do |
|---|---|---|---|
400 | BAD_REQUEST | The request is invalid: see the next section. | Fix the request using details.errors. Retrying unchanged returns the same error. |
401 | MISSING_TOKEN | No Authorization header. | Send Authorization: Bearer <your key>. |
401 | INVALID_TOKEN_FORMAT | The header is not Bearer <token>. | Fix the header. |
401 | INVALID_TOKEN | The key is malformed or doesn't exist. | Check the key, or generate a new one. |
403 | TOKEN_REVOKED | The key was revoked. | Generate a new key. |
403 | TOKEN_EXPIRED | The key passed its expiry date. | Generate a new key. |
403 | TOKEN_SUSPENDED | The key was suspended after repeated rate or quota violations. | Contact hi@multiples.vc. |
403 | USER_NOT_FOUND, INSUFFICIENT_PERMISSIONS | The key's owner is not on a plan with API access, or a trial key's owner is no longer on a paid plan. | Check your plan, or contact us. |
403 | PRIVATE_API_NOT_ENABLED | Private Data API only: the key is valid, but the Private Data API is not enabled for the account. | Contact hi@multiples.vc. |
403 | CATALOG_RESTRICTED | A trial key asked for a record outside its catalog. details.ids lists the refused ids. | Use catalog records, or contact us for full access. |
404 | NOT_FOUND | Private Data API only: the company, investor or transaction id doesn't exist, or the company or investor was deleted. | Check the id. Pass include_deleted=true to read a deleted company or investor. |
429 | RATE_LIMITED | More than 200 requests in the current minute. | Wait for Retry-After seconds, then retry. See Rate Limits. |
429 | MONTHLY_RECORD_LIMIT | Private Data API only: the request would take the account past its monthly record quota. | Request fewer new records, or wait for the reset on the 1st. |
500 | INTERNAL_ERROR | Something failed on our side. Nothing was charged. | Retry with backoff. If it persists, contact us. |
Validation errors (400)
On the Private Data API, a request with problems in its body or query returns message: "Invalid request" and one entry per problem in details.errors. The common ones:
| Problem | Example details.errors entry |
|---|---|
| A filter name that doesn't exist | unknown filter: target_vertical |
| A filter of the wrong type | target_country must be an array of strings |
| A value outside the accepted list | unknown target_verticals value "Pharmaceuticals"; did you mean "Biopharmaceuticals"? |
An unknown value inside {"all": [...]} | unknown target_themes.all value "fintech"; did you mean "FinTech"? |
| A tag filter in the wrong shape | themes must be an array of strings or {"all": ["..."]} |
| An empty match-all list | themes.all must be a non-empty array of strings |
| A field you can't sort on | sort field "revenue" is not sortable — see /lookup/{resource}.sort_fields |
| Paging past the first 10,000 results | cannot page beyond the first 10000 results (page * limit must not exceed 10000); narrow your filters instead |
| A query parameter an endpoint doesn't take | unknown query parameter: sort |
| A number query parameter that doesn't parse, or is repeated | valuation_min must be a single number |
Values for countries, regions, deal types and subtypes, verticals, themes, client focus, revenue model and company type must match the accepted lists exactly, case included. The error suggests the closest valid values: a case fix, the ISO code for a country name ("India" gives "IND"), the right filter when a value belongs to another list ("FinTech" is a theme, filter on themes), or close spellings. When nothing is close, it links to Filter values.
A few 400s use a different message and may have no details:
Request body must be a JSON object- the POST body is missing or not an object.Invalid pagination- a badpageorlimiton a GET list endpoint.- A path id that is not a UUID:
id must be a UUID. - Resolve request errors, e.g.
queries must be a non-empty array of stringsorq is required, e.g. ?q=nvidia.