agentlyleads docs
Getting started

Conventions

Content type

All requests and responses use application/json.

Status codes

CodeMeaning
200Request succeeded; all rows written (bulk write)
207 Multi-StatusPartial success — at least one row failed; inspect results[].status and results[].error
400 Bad RequestInvalid request body (malformed JSON, empty products array, more than 1,000 items)
401 UnauthorizedMissing, malformed, or revoked API key
404 Not FoundResource does not exist

Response shapes

Bulk write (POST /api/v1/products) returns a flat summary object:

{
  "created": 2,
  "updated": 1,
  "errors": 0,
  "results": [...]
}

List endpoints (GET /api/v1/products) wrap the array under a resource key:

{
  "products": [...]
}

Money

All monetary fields (price, cost) are JSON numbers — for example 199.99 — never strings. Decimal values stored in the database are coerced to Number at the API boundary.

Upsert idempotency

POST /api/v1/products is an idempotent bulk upsert:

  1. Each row is matched against an existing product first by sku, then by externalId (if sku is absent).
  2. If a match is found, only the fields present in the request body are updated. Omitted fields retain their current values — this is a merge update, not a full replace.
  3. If no match is found, a new product is created.

Re-sending the same payload updates rather than duplicates — safe to run on a schedule.

# First run: creates everything
# Every subsequent run: updates by SKU — no duplicates
curl -X POST https://agentlyleads.com/api/v1/products \
  -H "Authorization: Bearer $AL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"products":[{"name":"4G Router","sku":"RTR-4G","price":199}]}'

On this page