customer, vendor, item, location, subsidiary, department, classification, employee, transaction, customrecord_*). Add it to an agent once per lookup you need, with a display name that says what it finds — find_customer, find_item, find_sales_order_by_po — and pin the record and columns on each configuration so the agent only supplies the values.
Pass every value from a document in one call (search_values): a purchase order with 100 lines is one call, not 100. Each call makes one live request to NetSuite per matching stage (at most three); only a very large batch against many search columns is split into several statements so no single SuiteQL statement grows past a fixed size.
Authentication and enablement
Configured tool. Add a NetSuite integration under Settings → Integrations with the four token-based-auth values from your NetSuite account:- Account ID — Setup → Company → Company Information (e.g.
1234567or1234567_SB1for a sandbox). - Consumer Key / Client ID and Consumer Secret / Client Secret — from the Integration record (Setup → Integration → Manage Integrations) with Token-Based Authentication enabled. Every NetSuite account has its own integration records, so these are per workspace.
- Token ID and Token Secret — an Access Token (Setup → Users/Roles → Access Tokens) issued for that integration record, a user and a role with REST Web Services and SuiteAnalytics Workbook permissions.
401 means the token pair was not issued for the integration record whose consumer pair you entered. Bind the integration on the configured tool — the credential fields collapse into one integration picker.
Inputs
record_type— SuiteQL table to search, e.g.customer,item,transaction,customrecord_warehouse. Letters, digits and underscores only. Usually pinned per configuration.search_fields— columns to match against, in priority order (max 10). A value matching an earlier column ranks higher, so["itemid", "displayname"]prefers the SKU column over the name. Accepts a list or a comma-separated string.search_values— the values to look for (max 200 per call). Onematchesentry or oneunmatched_valuesentry comes back per value, in order. Duplicates are searched once.match_mode—auto(default):exact, thencontains, thenkeywords, each stage only for the values still unmatched.exact: whole cell must equal the value (SKUs, PO numbers, ids).contains: value appears anywhere in the cell (names).keywords: at least 60% of the value’s words (min 2, stop words dropped) appear in the cell in any order — for description-only lines, e.g.IMO, 3 String DC Disconnect Enclosed IP66findsIMO 3-String DC Disconnect Enclosure IP66. Always case-insensitive.filters— extra AND conditions as[{"field", "value"}](max 10), e.g.[{"field": "isinactive", "value": "F"}], or[{"field": "type", "value": "SalesOrd"}]whenrecord_typeistransaction. Also accepts"isinactive=F, type=SalesOrd".return_columns— extra columns to include with each match (max 30).idand the search fields are always included. Only columns of that record’s SuiteQL table are valid —itemhasitemid,displayname,itemtype,isinactive, but not a price (prices live in thepricingtable); an unknown column fails the call with NetSuite’sUnknown identifiermessage.limit— candidates kept per search value, 1–50 (default 5). The best is the match; the rest areadditional_candidates.
Typical configurations
Output
Structured content is the flat result (no envelope):matches[]— one per matched search value:search_value,values(object keyed by column:id, the search fields,return_columns; plain cells),matched_values(the column that matched → the matched cell),match_identifier(the NetSuite internal id — use it as theidin later steps),match_type(exact,containsorkeywords),confidence_score(1.0 for exact; 0.5–0.95 for contains, with a whole-word hit scoring at least 0.8; 0.5–0.9 for keywords by share of words found), andadditional_candidates[](match,match_identifier,confidence_score,product= the full row) for a reviewer to pick from.unmatched_values[]— search values with no row. Not an error.match_count,row_count,truncated,record_type,search_fields,search_values,match_mode,return_columns,completed_at.
Limits and side effects
- Read-only. One SuiteQL request per stage; at most three stages (
auto). Statements are capped at 300 match clauses, so a large batch against many columns runs as several statements per stage rather than one oversized one. - Up to 1,000 rows per pass are read;
truncated: truemeans more rows matched — narrow withfiltersor a more specific value. - Every table and column name is validated as a plain identifier and every value is quoted; there is no free-text SQL.
- Logs record the record type, fields, mode, counts and timing — never search values or rows.
Expected errors
NetSuite integration not configured…— no integration bound, or a credential field is empty.NetSuite account id "…" is not valid— the account id contains characters that cannot form a NetSuite hostname.validation error: …— a missing required field, an invalid identifier, an unknownmatch_mode, or a cap exceeded (values, fields, filters, columns, limit).NetSuite lookup on <record> failed: HTTP 400: …— NetSuite rejected the query, usually an unknown column or table for that record, or a role without SuiteQL access. The NetSuite detail is included; the query is not.