Making a request
The integrations endpoints, how to read an action's schema, and a complete Yelp example.
All site integration routes live under one base URL:
https://request.usestring.ai/v1/integrations| Route | Key needed | Returns |
|---|---|---|
GET /v1/integrations | No | The catalog: every site and its actions, with request bands and billing, but no schemas. |
GET /v1/integrations/{site} | No | One site's full manifest: each action's input and output JSON Schema, examples and billing. |
GET /v1/integrations/manifest.json | No | The same, for every site. |
POST /v1/integrations/{site}/{action} | Yes | Runs the action on the JSON body. |
{site} and {action} are the names in the catalog, such as yelp and business.
Running an action
Send a POST with your key and a JSON body that matches the action's input schema. Each
action's section in the catalog lists its input fields, and the manifest carries the same schema.
curl https://request.usestring.ai/v1/integrations/yelp/business \
-H "Authorization: Bearer $STRING_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "items": ["tonys-pizza-napoletana-san-francisco"] }'- The call is synchronous: the response arrives once every input has been read, so set your client's timeout to allow for an action that makes several requests. There is no job to poll.
- One call can cover many records. An action that reads records by id, such as Yelp
business, takes anitemsarray (up to 300 there) and reads the entries concurrently; an entry repeated initemsis read once. A paged action, such as Yelpsearch, takes apagescount instead. - The body is validated against the schema before any request is made. Invalid input
returns
400with the failing fields and costs nothing. See Responses & errors. - An empty body is treated as
{}. The body may be at most 1 MiB; a larger one returns413.
Worked example: Yelp business
This call asks for two Yelp businesses: one by its alias, and one by a URL that doesn't exist.
curl https://request.usestring.ai/v1/integrations/yelp/business \
-H "Authorization: Bearer $STRING_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
"tonys-pizza-napoletana-san-francisco",
"https://www.yelp.com/biz/this-business-does-not-exist-zz9"
]
}'The response is 200 OK: the first business came back as a row in data, and the second is listed in failures.
This is a real response, with the row cut down to a few of its fields:
{
"envelopeVersion": 1,
"integration": { "site": "yelp", "action": "business", "version": "1.0.0" },
"data": [
{
"encid": "mSMZJj2pFvttWLpcDmgrEA",
"alias": "tonys-pizza-napoletana-san-francisco",
"name": "Tony's Pizza Napoletana",
"url": "https://www.yelp.com/biz/tonys-pizza-napoletana-san-francisco",
"addressLine1": "1570 Stockton St",
"city": "San Francisco",
"postalCode": "94133",
"regionCode": "CA",
"countryCode": "US",
"latitude": 37.80038939,
"longitude": -122.40903343,
"phone": "(415) 835-9888",
"rating": 4.2,
"reviewCount": 9018,
"priceRange": "$$",
"isCurrentlyOpen": true
}
],
"failures": [
{
"input": "https://www.yelp.com/biz/this-business-does-not-exist-zz9",
"error": "Yelp does not resolve this business: \"this-business-does-not-exist-zz9\""
}
],
"warnings": [],
"requests": [
{
"url": "https://graphql-mobile-api.yelp.com/gql/mobile",
"requestType": "request_standard",
"requestId": "d2d57cbf-1421-4c28-aeca-1bd6b33ba12f"
},
{
"url": "https://graphql-mobile-api.yelp.com/gql/mobile",
"requestType": "request_standard",
"requestId": "e84222ff-571c-4cf8-9640-4c05c6bd9c21"
},
{
"url": "https://graphql-mobile-api.yelp.com/gql/mobile",
"requestType": "request_standard",
"requestId": "b9f67a31-d7e0-46e1-8892-d7597c040eee"
}
],
"billing": { "mode": "passthrough", "calls": 1, "rows": 1 },
"traceId": "75b7d7a0f6830d88ede9baf9b6cc3934"
}Reading it:
dataholds one row per business found. The full row also has categories, review counts by star and by language, opening hours, ordering partners and the newest review; the Yelp page lists every field.failuresnames each input exactly as you sent it, with the reason it produced no row.requestsshows the action made three requests, each billed at therequest_standardrate. Those three requests are what this call cost. See Billing.traceIdidentifies the call. Include it when you contact support.
Responses & errors explains every field and status code.
Reading the schemas
The catalog pages in these docs are generated from the manifest, so you rarely need to read it yourself. Read it when you want to generate a client, validate input before sending it, or notice when an integration changes.
curl https://request.usestring.ai/v1/integrations/yelpThe response, shortened:
{
"manifestVersion": 2,
"sites": [
{
"name": "yelp",
"title": "Yelp",
"description": "Yelp business records, search by term and location, and business reviews, read from Yelp's GraphQL API.",
"version": "1.0.0",
"hosts": ["yelp.com"],
"actions": [
{
"name": "business",
"description": "Read Yelp business records by id, alias or URL: …",
"input": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": { "type": "string" },
"description": "Yelp business ids (encid), aliases, or yelp.com/biz/ URLs",
"minItems": 1,
"maxItems": 300
}
},
"required": ["items"],
"additionalProperties": false
},
"output": { "type": "array", "items": { "…": "the schema of one row" } },
"examples": [{ "input": { "items": ["…"] }, "output": [{ "…": "…" }] }],
"requests": { "min": 1, "max": 2, "per": "item" },
"billing": { "mode": "perRow", "usd": 0.002 }
}
]
}
]
}inputandoutputare JSON Schemas.outputdescribes the wholedataarray, sooutput.itemsis the schema of one row.hostsare the only domains the site's actions request.requestsandbillingare explained in Billing.billingis the price the action is listed at, which isn't charged yet.versionandmanifestVersionare explained in Versioning.
An unknown {site} returns 404.
Polling for changes
The three GET routes send a strong ETag, a Last-Modified time and Cache-Control: public, no-cache. Send the
ETag back in If-None-Match, or the time in If-Modified-Since, and an unchanged manifest answers
304 Not Modified with no body. That makes checking for a new version cheap.
curl -i https://request.usestring.ai/v1/integrations \
-H 'If-None-Match: "6749a615aa22339d4c3aa2bf6c9830cd"'