For child-to-parent (many-to-one) traversal, use dot notation in the SELECT clause: SELECT Id, Account.Name FROM Contact WHERE Account.Industry = 'Technology'.
For parent-to-child (one-to-many) sub-queries, embed a SELECT inside the FROM clause: SELECT Id, Name, (SELECT Id, CloseDate FROM Opportunities) FROM Account.
GET or POST to /services/data/vXX.0/query?q={URL-encoded SOQL}; use POST /services/data/vXX.0/query for long queries that exceed URL length limits.
The response includes 'totalSize', 'done', and 'records'; if 'done' is false, follow 'nextRecordsUrl' to paginate until done is true.
For sub-query results, each parent record's sub-query results are nested under the relationship name with their own 'records' array and 'done'/'nextRecordsUrl' if the child result set is large.
Use LIMIT and OFFSET or cursor-based pagination (nextRecordsUrl) rather than OFFSET alone for large datasets, as OFFSET beyond 2,000 is not supported.
Known gotchas
Parent-to-child sub-queries are limited to one level of nesting — you cannot nest a sub-query inside a sub-query.
SOQL does not support full outer joins; a child-to-parent traversal that references a null parent returns null for the parent fields, not an error — filter explicitly if nulls cause downstream problems.
The query API is synchronous and subject to a 120-second timeout; for very large result sets, use Bulk API 2.0 query jobs instead.
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