These rules describe Standard v2 keys and OAuth connections in the 5.10.0 source package. Follow each operation's OpenAPI schema and your installation's capability export for its exact fields, limits, and permission requirements. Legacy keys and CloseBot retain their existing contract.
Request validation
Shared CRM JSON writes require Content-Type: application/jsonand a JSON object. Malformed JSON and non-object bodies return 400. An unsupported media type returns 415; a body beyond that endpoint's byte limit returns 413. Endpoint validators still check required fields and domain rules.
A list limit must be one plain decimal integer within that operation's documented range. Most collections allow up to 100, some allow 50, and a few state a different maximum. Filters and timestamp units are also operation-specific. Resource IDs are opaque strings.
Pagination and list bounds
Cursor lists
Contacts without search, tasks, opportunities, message history, and campaign lists use cursor plus hasMore. Standard v2 and OAuth conversation lists, appointment rosters, and pipelines also support their documented bound cursors.
Bounded lists and lookups
Contact search and exact email lookup are not cursor exports. Calendars, appointment types, contact fields, and webhook subscriptions have their own list behavior. Some discovery lists report meta.truncated instead of a continuation cursor.
Pass a cursor unchanged with the same credential, location, and filters. Stop when hasMore is false. A filtered cursor page can be empty while more pages remain, and a final page can still include a cursor. Treat bounded totals as advisory; do not use them to decide when to stop.
CSV export content
Report, audit, and suppression export content endpoints return JSON, not a raw CSV download. Each response contains one CSV part in data: contentType is text/csv, part is a zero-based index, and csv is that part's text. Join parts in order to rebuild the file.
{
"data": { "contentType": "text/csv", "part": 0, "csv": "..." },
"meta": { "limit": 1, "hasMore": true, "cursor": "...", "truncated": false }
}Pass meta.cursor to the next content request. Stop only when meta.hasMore is false, even if a part has no rows. A true meta.truncated means the export stopped at its row limit and is incomplete. It does not describe an audit resume action or the ordinary suppressions list.
Errors
Branch on HTTP status and error.code, not the wording of error.message. Common integration responses include 400 VALIDATION_ERROR, 403 FORBIDDEN, 404 for a missing accessible resource, 409 VALIDATION_ERROR for conflicts, 413 for body limits, 415 for media type, and 429 for throttling. Unexpected failures use a generic internal error. OAuth token endpoints use their own protocol errors.
The Seedly SDK preserves a valid error envelope's status, code, message, and details. For malformed error responses it uses a fixed HTTP_ERROR fallback, or RATE_LIMITED for HTTP 429. Network failures remain network failures.
Rate limits
Core live resource budgets are 120 reads and 30 writes per minute per credential and resource. Test budgets are 30 reads and 10 writes. Standard v2 keys and OAuth grants also have an across-route ceiling of 1,200 requests per minute, or 300 in test mode. Other operation work budgets can apply. Legacy keys and CloseBot do not gain this across-route ceiling; their existing resource budgets remain.
Read X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset when present. Reset is a Unix time in seconds. A 429 response includes Retry-After in seconds. Some refusals occur before a resource budget and may omit these headers.
Safe retries
A timeout does not prove a write failed. General OAuth contact, task, opportunity, and conversation writes, and Standard v2 or OAuth campaign draft, send, and schedule actions require the documented Idempotency-Key. Reuse the same key with the same method, target, and payload only where that operation documents replay protection. Changed retries can conflict. The SDK does not retry writes automatically.
General Standard v2 writes, legacy writes, and webhook administration have no blanket retry guarantee. Adding an Idempotency-Key to an undocumented route does not make it safe to replay. Recheck the installation's OpenAPI contract before retrying a send or billable action.