Skip to main content
Vendor Update API

Authentication

All requests require an API key in the request headers. Headers:

Request

Content-Type: application/json

Path Parameters

Body Parameters

The request body has a single top-level key, vendorData. All fields inside vendorData are optional — only the fields you include will be considered for update. Fields you omit are left untouched. Two schema rules apply to the whole payload:
  • At least one field is required. vendorData must contain a minimum of one property; {"vendorData": {}} is rejected with 400 VALIDATION_ERROR.
  • Unknown keys are rejected. vendorData, address, communications, and each customFields entry all reject properties that are not listed below with 400 VALIDATION_ERROR — they are not silently ignored.

Address Fields

vendorData.address accepts the following properties. All are optional and merged with the existing address — any key you omit (or send empty) keeps its current value, so you only need to send the parts that change. The one exception is country, which falls back to India rather than the existing value when the vendor is DOMESTIC.
Address validation is all-or-nothing: the first invalid field rejects the entire address update with a single INVALID_ADDRESS error whose message names the offending field (for example, Given address is not valid. Invalid state code). No partial address is written.

Communications Fields

vendorData.communications configures who receives payment confirmation emails. Each list contains user ids / slugs from your organization. Behavior to be aware of:
  • Each list is replaced, not appended to. Sending to: ["user_a"] makes user_a the only “To” recipient.
  • Merged per list. Lists you omit — or send as an empty array — keep their current recipients. There is no way to clear a list through this endpoint.
  • Duplicates are removed within each list.
  • All ids are validated together. If any id across to, cc, and bcc is not a user in your organization, the whole communications update is rejected with INVALID_USER_IN_COMMUNICATIONS and the offending ids are returned in wrongUserSlugs.

Custom Fields

vendorData.customFields is a map keyed by the flex-field slug configured for your organization. Each value is an object requiring both type and value: Expected value per type: Each slug is validated and applied independently, so one bad entry does not block the others — check context.updates.customFields.<slug> for each. Notes:
  • The expense-head slug cannot be updated through this endpoint and always returns TAG_NOT_ALLOWED.
  • Use the Tags APIs to look up valid slugs and, for DROPDOWN, the tag value ids to send.

Full Request Body Example

Every supported field in one payload — in practice, send only the ones you want to change:

Code Examples

Success Response

HTTP Status: 200 OK The endpoint always returns 200 OK when the request itself is valid — even when individual fields fail to update. Check ok first, then inspect context.updates.<field> to see the per-field outcome. A 200 with ok: false means the write itself failed and nothing was applied — see Update Failed. Response Fields: Some fields attach extra metadata when they fail:

Response Example — Successful Multi-Field Update

Response Example — Mixed Success and Failures

Response Example — communications with Unknown Users

Response Example — customFields Mixed Outcome

Per-Field Error Codes

Error Responses

Validation Error

HTTP Status: 400 Bad Request
Returned before any field is processed when the body does not match the schema — a bad email format, a name outside 1-255 characters, an empty vendorData, an unknown property, a customFields entry missing type or value, or a locality other than DOMESTIC / INTERNATIONAL.

Update Failed

HTTP Status: 200 OK
Returned when writing the changes fails. The whole update is rolled back as a single transaction — no field is applied, including ones that validated successfully. Note that this envelope carries errorCode (not code) and has no context, so check ok before reading context.updates. Safe to retry.

Vendor Not Found

HTTP Status: 404 Not Found

Access Denied

HTTP Status: 403 Forbidden
Returned when the caller is neither an admin / bookkeeper nor the vendor’s owner.

Authentication Errors

HTTP Status: 401 Unauthorized

Permission Errors

HTTP Status: 403 Forbidden

Internal Error

HTTP Status: 500 Internal Server Error

Best Practices

  • Send only the fields you want to change — omitted fields are left untouched
  • Always inspect context.updates.<field> for the outcome; a 200 OK does not guarantee every field was applied
  • For phone, normalize to E.164 (+{country_code}{number}) before sending — values without + are rejected with INVALID_NUMBER
  • For address, the API merges with the existing record. Send only the keys you want to change rather than the full address — and use pinCode, not zipCode, to change the postal code
  • For communications, each list you send replaces that list. Fetch the current recipients first and send the full intended list, rather than just the ids you are adding
  • For customFields, the type you send must exactly match the field’s configured type — a mismatch is rejected per-field with INVALID_TAG_TYPE
  • For DROPDOWN custom fields, send the tag value id, not the displayed label — a label is rejected with INVALID_VALUE_ID
  • Use the Vendor Details API to fetch the current state, and the Vendor Audit Trail API to inspect change history after updates