String API
Site integrations

Responses & errors

The run envelope every action answers with, partial results, and what each status code means.

Every call that reaches an action's code answers with the same JSON object, the run envelope, whether it succeeded or not. Calls stopped before that point answer with a short error body instead: invalid input, an unknown site or action, and a key Web Access refused. Status codes lists which is which.

The run envelope

{
  "envelopeVersion": 1,
  "integration": { "site": "yelp", "action": "business", "version": "1.0.0" },
  "data": [{ "encid": "mSMZJj2pFvttWLpcDmgrEA", "name": "Tony's Pizza Napoletana" }],
  "failures": [{ "input": "not-a-business", "error": "Yelp does not resolve this business: \"not-a-business\"" }],
  "warnings": [],
  "requests": [
    { "url": "https://graphql-mobile-api.yelp.com/gql/mobile", "requestType": "request_standard", "requestId": "d2d57cbf-…" }
  ],
  "billing": { "mode": "passthrough", "calls": 1, "rows": 1 },
  "traceId": "75b7d7a0f6830d88ede9baf9b6cc3934"
}
FieldTypeDescription
envelopeVersionintegerThe shape of this object. Currently 1. See Versioning.
integration.sitestringThe site you called, such as yelp.
integration.actionstringThe action you called, such as business.
integration.versionstringThe site's version that served the call, such as 1.0.0.
dataarrayThe rows, each matching the action's output schema. Always an array; empty when nothing was found.
failuresarrayOne entry per input that produced no row. Always an array.
failures[].inputstringThe input exactly as you sent it, such as an entry of items.
failures[].errorstringWhy that input produced no row.
warningsarrayProblems the action worked around without failing an input, such as a partial error from the site's API. Always an array, usually empty.
warnings[].sourcestringWhere the warning came from.
warnings[].messagestringWhat happened.
requestsarrayEvery Web Access request the action made that got a response. These are what the call was billed for.
requests[].urlstringThe URL requested.
requests[].requestTypestringThe rate the request was billed at, such as request_standard. See Billed request type. Absent when the request wasn't billed.
requests[].requestIdstringThe request's id in Web Access, the same value /v1/fetch returns in x-request-id.
billingobjectHow this call is charged. See Billing.
billing.modestringThe billing mode applied to this call. Currently always passthrough.
billing.usdnumberThe action's price, under the perCall and perRow modes only.
billing.factornumberThe multiplier applied to the requests' cost, under the multiplier mode only.
billing.callsinteger1 when the call counts as a charged call, 0 when it failed outright.
billing.rowsintegerThe number of rows in data.
errorstringPresent only when the call failed as a whole: the first input's failure, or the error that ended the call.
traceIdstringThe call's trace id, also sent as the x-trace-id response header. Include it when you contact support.

New fields can be added to the envelope without notice, so ignore fields you don't recognise.

Partial results

An action reads each input on its own. When some inputs produce rows and others don't, the call still answers 200 OK: the rows are in data and the rest are in failures. Always check failures, even on a 200.

{
  "data": [{ "encid": "mSMZJj2pFvttWLpcDmgrEA", "name": "Tony's Pizza Napoletana" }],
  "failures": [{ "input": "not-a-business", "error": "Yelp does not resolve this business: \"not-a-business\"" }]
}

To retry, send just the failures[].input values again. When every input fails, the call answers 502 instead, with the first failure in error.

A 200 with an empty data and empty failures is a successful call that found nothing, such as a search with no results.

Status codes

StatusWhenBody
200The call produced rows, possibly with some failures, or found nothing.Run envelope
400The body isn't valid JSON or doesn't match the action's input schema.{ error, message, issues }
401The key is missing, malformed, invalid or revoked.Web Access's error, unchanged
402Your balance can't cover a request the action needed.Web Access's error, unchanged
403Your organization isn't allowed to make a request the action needed.Web Access's error, unchanged
404The site or action doesn't exist.{ error, message }
413The body is larger than 1 MiB.{ error, message }
429Your organization is over its rate limit.Web Access's error, unchanged
500The integration itself misbehaved, for example by returning a row that broke its own schema.Run envelope with error, or { error, message } if the action never started
502Every input failed, or the call ended on an error from the site.Run envelope with error
504The call ran out of time.Run envelope with error

400: invalid input

Input is validated before any request is made, so a 400 costs nothing. The body has the same shape as a /v1/fetch validation error, so one handler covers both. Each entry in issues names the failing field as a dotted path, with array positions counted from 0:

{
  "error": "Validation error",
  "message": "type: 1 has type \"integer\", want \"string\"",
  "issues": [{ "field": "items.0", "message": "type: 1 has type \"integer\", want \"string\"" }]
}

A missing required field, or a field the schema doesn't define, is reported against that field's name.

401, 402, 403 and 429: passed through from Web Access

Each request an action makes uses your key. When Web Access refuses one of them with 401, 402, 403 or 429, the call stops at once and you get that response's status and body unchanged, along with its Retry-After header when it has one. There is no envelope and no partial result: the same refusal would apply to every other request in the call. The bodies are the ones described in Errors.

404: unknown site or action

{ "error": "Not found", "message": "unknown site nope" }

The catalog lists the valid names. Names are lowercase.

500, 502 and 504: the call failed

These answer with the run envelope, so you still see requests (what was billed) and failures. error says what went wrong and billing.calls is 0.

  • 502 means the site couldn't be read: every input failed, or the site's API returned an error that ended the call. Retrying later may succeed.
  • 500 means the integration broke its own rules, such as producing a row that doesn't match its output schema. That's a bug on our side; send us the traceId.
  • 504 means the call ran out of time before it finished.

Getting help

Every response carries an x-trace-id header, and every envelope carries the same value as traceId. Include it when you contact [email protected], along with the requestId of any request in requests you have a question about.