Paging, filtering, errors and rate limits
The conventions every Nova operation follows for lists, record identity, updates, the error envelope, idempotency and rate limits.
These rules hold for every operation, whether it is in the documented API reference or only in the operation index (Find the operation to call).
Lists
List operations take page and page_size (and sometimes sort_by /
sort_order); most also take a free-text query (or q) that matches what
the app's own search box matches. The reference lists each operation's
filters. Ask for what you need: large pages are slower and count against the
same rate limit.
curl -s "https://app.novabmp.com/v1/crm/accounts/?query=smith&page=1&page_size=25" \
-H "Authorization: Bearer $NOVA_KEY"
Records
- Address a record by its
uid, never by a number. See How records are identified. - A uid of the wrong type returns
404, the same as a record that does not exist, so a mistyped uid and a missing record look alike. - Email draft attachment inputs accept File UIDs returned by uploads. Keep
those references unchanged when saving a draft. Draft body responses include
attachment_file_uidsand authorizedattachment_filesentries containinguid,original_filename,content_typeandsize_bytes, so a reopened attachment retains its display and preview information. - Updates send only the fields you change. Unknown fields are refused with
422naming the field. - Archiving hides a record; nothing is deleted. An archived account can still
be read in full; changing it answers
409 account_archiveduntil someone restores it.
The error envelope
Every error has the same outer shape. Switch on error.code; show
error.message; quote error.request_id if you contact support.
{
"error": {
"code": "account_archived",
"message": "This account is archived. Restore it to make changes.",
"request_id": "0f5c1d2e-…",
"details": {"cta": {"kind": "restore_account"}}
},
"detail": "This account is archived. Restore it to make changes."
}
Some refusals carry their specific reason inside detail rather than in
error.code (which then reads forbidden). Errors and how to recover lists every code,
where to find it and what to do about it.
Idempotency
Operations that list an Idempotency-Key header in the reference (creating
and updating accounts, contacts, locations, quotes, invoices, tasks,
recording a payment, among others) replay the first response when the same
key comes back, so a retried request never makes a duplicate. Sending the
same key with a different body answers 409 idempotency_payload_mismatch.
curl -s -X POST https://app.novabmp.com/v1/tasks \
-H "Authorization: Bearer $NOVA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1e0c7a-5d2b-4e8f-9a31-2c7b8d4e0f11" \
-d '{"title": "Call Smith about the furnace filter"}'
Where an operation does not take the header, search before you create and
keep the uid you get back, so a retry updates instead of duplicating.
Rate limits
Each credential has a per-minute limit, the organization has one across all
its software, and an organization can give a credential a daily cap on
changes. Going over answers 429 rate_limit_exceeded with
error.details.retry_after_seconds. Wait that long; never retry in a tight
loop. Numbers and the daily cap are in Rate limits, daily caps and other limits on a credential.
Versioning
The documented tier carries the release id in the reference document's
info.version. Fields are added, never silently removed; a removal is
announced in the release notes first.
Email list views and deletion
Mailbox and unified email message lists accept filters.view as messages or threads. In Threads, grouping happens before cursor pagination. Each row carries the authorized matching message UIDs, message count, unread count and attachment indicator for that conversation. Drafts remain separate rows. Read a conversation's message list to retrieve its earlier messages; their bodies and attachments load through the normal authorized endpoints.
Ordinary email deletion uses the message action trash: true and moves the message to Deleted Items. delete_forever: true is allowed only after that move; otherwise the action returns email_message_not_in_deleted_items without deleting anything. Batch actions return opaque message UIDs in their results. Emptying a folder takes its opaque folder UID and requires the folder deletion permission.
Editing a scheduled customer notification
Read GET /v1/customer-notifications/{notification_uid}/preview, then send PUT /v1/customer-notifications/{notification_uid} with the returned revision, recipient_address, subject_line, body_text, and a future timezone-aware at. The opaque notification UID identifies one occurrence throughout scheduling and delivery. Read editable_fields and can_edit before offering edits. Editing requires customer_notifications.operate. Engine operations also require the automations entitlement; log reads remain available independently of that entitlement. Signing reminders also require signer management and signing resend permissions.
A stale revision or an already-claimed send returns 409 without saving changes. Invalid addresses, empty wording, and past or timezone-free send times return validation errors. A save does not send the message, change the customer's contact methods, or bypass consent, delivery limits or quiet hours. Sent entries remain read-only.
Customer notification lists support cursor pagination, record and customer filters, delivery state, channel, source, attention, and date ranges (date_from, date_to, time_zone). /health reports processing health; /export requires the export permission. POST /v1/customer-notifications/{notification_uid}/operate takes revision and action (send_now, retry, resend); resend requires its own permission. Operations retain domain delivery checks. The platform equivalents are read-only.