POST to /services/data/vXX.0/jobs/query with 'operation':'query' and a SOQL string that includes a parent relationship field (e.g. Account.Name on Contact) to create the query job
Poll GET /services/data/vXX.0/jobs/query/{jobId} until 'state' is 'JobComplete', checking 'numberRecordsProcessed'
GET /services/data/vXX.0/jobs/query/{jobId}/results?maxRecords=50000 with Accept: text/csv to download the first result chunk; capture the Sforce-Locator header value
If Sforce-Locator is not null, repeat the GET with locator={value} query param to retrieve subsequent pages until the response header is null
DELETE /services/data/vXX.0/jobs/query/{jobId} to abort if needed, or let it expire after the retention window
Known gotchas
Query jobs do not support all SOQL clauses — GROUP BY, aggregate functions, and semi-joins are not supported; use a standard SOQL job or Bulk API ingest instead
The Sforce-Locator header is absent on the final page, not an empty string; check for header presence explicitly
Parent relationship fields in the SOQL are returned as flattened dot-notation columns in the CSV (e.g. 'Account.Name'), not nested objects
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp