POST /services/rest/record/v1/vendorbill and returns the bill’s internal id and a link to open it. Display name “NetSuite Create Vendor Bill”. Off by default.
Everything account-specific — custom form, approval status, custom custbody_* / custcol_* fields — is an input the admin pins on the configured tool, never code.
Authentication and enablement
Configured tool bound to a NetSuite integration (account id, token id/secret, consumer key/secret — see NetSuite Lookup). The role behind the token needs permission to create bills.Inputs
Header:vendor_id— NetSuite internal id of the vendor. When set, no vendor search runs.vendor_name— searched (companyname LIKE, first match) to find the vendor. Required unlessvendor_idis given.invoice_date— required,YYYY-MM-DD.due_date— optional.tran_id(vendor’s invoice number),memo,currency(internal id),subsidiary_id.custom_form_id— the bill form’s internal id; empty uses the role’s default form.approval_status— internal id:1Pending Approval,2Approved,3Rejected. Needs bill approval routing enabled in the account.exchange_rate— number; omitted means NetSuite’s rate for the day.department_id,location_id,class_id— header classification.dry_run— configuration and testing only (hidden from the agent).truecreates nothing (see Output). Defaultfalse.custom_fields— header custom fields keyed by script id (custbody_*, orcseg*for a custom segment), sent as given: a plain value for text, number, date and checkbox fields,{"id": "…"}for list and record fields, e.g.{"custbody_reviewed": true, "custbody_approver": {"id": "42"}}. A JSON string of that object is accepted too (the configure form’s JSON editor), and so arecustbody_*keys written at the top level of the call.nullvalues are dropped. Standard fields are not accepted here, so the agent cannot set fields such as the AP account or posting period. Same convention as NetSuite Create Sales Order.custom_fields_defaults,line_custom_fields_defaults— configuration only: custom fields applied to every bill / every line, under the agent’s values (anullvalue from the agent clears a default).
line_items, required): account_id (GL expense account, required), amount (> 0, required), memo, department_id, location_id, class_id, custom_segments (["cseg_x=Display Name", …], display names resolved to ids by lookup), and custom_fields — line custom fields (custcol_*), same convention as the header.
All ids are validated as digits before anything is sent.
Output
Success:bill_id, tran_id, vendor_id, vendor_name, invoice_date, due_date, total_amount, currency, memo, status (from approval_status; “NetSuite default” when unset), line_item_count, line_items[], netsuite_url, completed_at.
Dry run: status: "dry_run", dry_run: true, request (method, full url, headers with Authorization: OAuth [REDACTED], and the exact JSON body), lookups_performed[], vendor_id, vendor_name, total_amount, line_item_count. With vendor_id and no custom_segments a dry run makes no NetSuite call at all; otherwise the read-only vendor search and segment lookups still run to build the body, and lookups_performed lists them.
Limits and side effects
- Creates exactly one bill per successful call; no duplicate check — the same call twice creates two bills.
- Expense lines only (no item lines). Attach the source document with NetSuite Attach File.
Expected errors
NetSuite integration not configured…, missing consumer pair, invalid account id — configuration.validation error: …— no vendor, a name where an id is expected, a non-positive amount or exchange rate, or acustom_fieldskey that is not acustbody_*/custcol_*/cseg*script id.failed to find vendor '…'— the name search matched nothing; passvendor_id.failed to create vendor bill: create vendor bill returned HTTP 400: …— NetSuite’s own message (e.g. a field not on the chosen form).
status: "limitation"): retrying the same call cannot succeed, so they go straight back to the agent. Network errors and 5xx answers are retried.