Appearance
POST /public/v1/organizations/batch
| Auth | Required |
| Scope | organizations:write |
| Idempotency-Key | Required |
Upserts 1 to 100 organizations in one request. Use this for a nightly database load. The body rules match POST /organizations.
Request
json
{
"items": [
{
"external_reference": "sf-001",
"external_source": "salesforce",
"name": "Acme Mortgage",
"client_type": "lender"
},
{
"external_reference": "sf-002",
"name": "Northgate AMC",
"client_type": "amc",
"phone": "(615) 555-0140",
"email": "orders@northgate.example",
"website": "https://northgate.example",
"address_line1": "10 Commerce St",
"city": "Nashville",
"state": "TN",
"postal_code": "37203"
}
]
}A schema error (invalid phone, unknown client_type, empty items) fails the whole request and writes nothing. A business-rule error on one row returns action: "error" for that row. The other rows still save.
Use a new idempotency key for each batch whose body changed.
Response
json
{
"results": [
{
"index": 0,
"external_reference": "sf-001",
"action": "created",
"id": "8f0c…",
"error_code": null,
"message": null
}
]
}action is created, updated, or error. On error, id is null and error_code is one of name_conflict, ambiguous_match, external_reference_conflict, contact_conflict, or validation_error.
Each successful row emits organization.upserted after the batch commits.
Try It
Try It calls https://staging-api.appraiserflow.ai/public/v1 with an af_test_ key. The key stays in sessionStorage. af_live_ keys are blocked. Live server calls use https://api.appraiserflow.ai/public/v1 with an af_live_ key kept on your server.