- Brand
- Instrumentl
- Category
- Operations
- Primary Subcategory
- Government Procurement & Contract Search
Integration details
Description
Instrumentl integration for nonprofits. Make Instrumentl a native part of your AI workflow – an intelligent partner that helps you find, win, and manage grants faster, directly in ChatGPT.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Government Procurement & Contract Search
- Secondary Subcategories
- None listed
- Brand
- Instrumentl
- Access
- Account required
- First tracked
- 2026-09-13
- Tool count
- 31
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for Instrumentl
Get updates when Instrumentl’s Discoverability Score or category rank changes.
Competing in ChatGPT Government Procurement & Contract Search
View Category31 tools agents can invoke
Delete one or more expenses by their API IDs (e.g. `exp_...`). Best-effort: critically required expenses linked to external systems (QuickBooks, Sage Intacct, etc.) cannot be hard-deleted and are returned in the `failed` array with a reason; other expenses in the same call are still deleted. The response shape is: { deleted_ids: ["exp_...", ...], failed: [{id: "exp_...", reason: "..."}, ...] } Possible failure reasons: - "not_found": the id doesn't exist or belongs to a different account - "not_authorized": the caller lacks permission to delete this expense - "linked_to_external_system": the expense is mirrored from an external integration and must be removed there first
bulk_destroy_expenses
Update one or more expenses by their API IDs (e.g. `exp_...`). Best-effort: expenses that don't exist, belong to a different account, or that the caller lacks permission to modify are returned in the `failed` array with a reason; other expenses in the same call are still updated. Currently the only supported update is toggling whether an expense is ignored. Ignored expenses are excluded from budget totals but kept on the account for reference. Pass `ignored: true` to mark expenses as ignored, or `ignored: false` to restore them. The response shape is: { updated_ids: ["exp_...", ...], failed: [{id: "exp_...", reason: "..."}, ...] } Possible failure reasons: - "not_found": the id doesn't exist or belongs to a different account - "not_authorized": the caller lacks permission to update this expense
bulk_update_expenses
Add one or more expenses to a grant's budget. Each expense attaches to a specific expense category (an `ec_...` API ID) within a saved grant (an `save_...` API ID); call `list_budgets` first to find the right category and its remaining budget. Amounts are integer cents (e.g. `12500` = $125.00). Best-effort: each expense is created independently. Items that fail (unknown or forbidden grant/category, validation errors) are returned in the `failed` array — each carries its input fields and a reason — while the rest are still created. Pass `dry_run: true` to preview the budget impact WITHOUT creating anything. The preview reports, per category, the projected remaining budget, whether it would be overspent, and any expenses that already exist in that category — useful to catch a planned expense the user may want to update rather than duplicate. Prefer a dry run first whenever an expense might exceed a budget or already exist. To update or remove existing expenses, use `bulk_update_expenses` or `bulk_destroy_expenses` instead of creating new ones. Create response shape: { created_ids: ["exp_...", ...], failed: [{index, reason, saved_grant_id, expense_category_id, amount_cents, errors?}, ...], budget_impact: [{expense_category_id, category_name, remaining_cents, overspent}, ...] } Dry-run response shape: { projected: [{saved_grant_id, expense_category_id, category_name, budgeted_cents, current_remaining_cents, added_cents, projected_remaining_cents, overspent, existing_in_category, existing_in_category_has_more}, ...], failed: [...] } Possible failure reasons: - "not_found": the grant or category doesn't exist or belongs to a different account - "not_authorized": the caller lacks permission to add to this grant - "invalid": the expense failed validation (details in `errors`)
create_expenses
Create Document Library folders. Pass up to 5 entries in `folders`. - name: The new folder's name. - parent_folder_id: (optional) API ID for the new folder's parent folder. Omit it, or pass null, to create the folder at the top level. Folder name rules: - 1 to 255 characters. - Only letters, numbers, spaces, and the following characters: - _ . ( ) - Must be unique within the parent folder. Notes: - Folders can be nested at most 10 levels deep. - To create more than 5 folders at once, call this tool again. - Use `list_folders` to find parent folder ids.
create_folders
Delete one or more documents (`doc_...`) and document links (`encryptedcred_...`) from the account's Document Library by their API IDs. Pass at least one of `documents` or `document_links`. Best-effort: items that can't be deleted are returned in the `failed` array with a reason, other items in the same call can still be deleted. Deleting is permanent from the user's point of view, so confirm with the user before calling this tool. The response shape is: { deleted_ids: ["doc_...", "encryptedcred_...", ...], failed: [{id: "doc_...", reason: "..."}, ...] } Possible failure reasons: - "not_found": the id doesn't exist, was already deleted, or belongs to a different account - "not_authorized": the caller lacks permission to delete this item Users usually refer to documents by name, so use `list_documents` to find document ids.
delete_documents
Start snippet/answer generation for a grant application. The grant must be saved in the user's tracker. Use `list_saved_grants` to find the saved grant and pass it as `saved_grant_id`. The saved grant must: - Be in the "Planned" status. If not, update its status using `update_saved_grant`. - Have a current or upcoming funding cycle (rolling grants do not need funding cycles) with a live application form. Use `request_application_form` first if no live form exists. Use `list_documents` to find relevant Documents you wish to use for snippet generation. Relevant documents include past grant application proposals and any others that include relevant context for this application. Pass them in as `documents`. - If no documents are provided by the user, ask. Do not call this tool until the user specifies at least 1 document. `user_filters` are optional details that help tailor the generated answers: - contact_first_name. - type_of_request: "programmatic" or "operational". - This pairs with either `program_name` (programmatic) or `organization_name` (operational). Omit `user_filters` entirely to leave previously saved filters unchanged, or pass it to overwrite them. Snippet generation is asynchronous. This tool only starts the process, so you can use `list_snippets` to check the status of the snippet generation. It takes 3 minutes on average for snippet generation to complete, poll no more than every 30 seconds starting at 3 minutes Call this tool again, with any updated documents or user filters, to re-generate the snippets for the saved grant.
generate_snippets
Retrieve the Instrumentl account the caller is authorized to act in.
get_current_account
Hide a previously-saved grant by marking its SavedGrant as no longer saved (`saved: false, hidden: true`). Pass the SavedGrant's `id` (e.g. `save_...`). This is reversible and non-destructive: the SavedGrant and any application data attached to it (submission goals, tasks, expenses, etc.) are preserved, and the grant can be saved again later. To find the right `saved_grant_id`, list the project's saved grants (`list_project_matches` filtered by saved status, or look up via `list_project_matches`'s `saved` filter).
hide_saved_grant
List the grant application form questions. Pass the grant's `id` from `list_grants` or `search_grants` as `grant_id`. If a user gives a grant name, resolve it with one of those tools first. Never guess an id. A grant has 1 application form per funding cycle. By default this returns the form of the most recent funding cycle; pass `funding_cycle_id` (from the grant's `funding_cycles` in `list_grants`) to pick another cycle. meta.funding_cycle_id names the cycle returned; null means the form is not tied to a cycle. Each item returns the question text, and addition information about the question like section, validation etc. Respect these limits when drafting answers. An empty list means the grant has no live application form. Use the `request_application_form` tool to request that the form be built, if it is available to you, or request it through the Instrumentl UI. Each account can make up to 30 application question retrievals through MCP per calendar month, resetting on the first at 00:00 UTC. Calls that return an empty list do not count toward this limit.
list_application_questions
List the current user's budgets — one per saved grant that has a budget set up or a draft budget version — to decide which budget an expense belongs to or to review drafts. Saved grants with neither expense categories nor a draft are omitted (unless requested by saved_grant_ids). Optionally narrow the results (filters compose with AND; omit all to list every budget). The user usually refers to a budget by name rather than id: - grant_name: the grant's name (case-insensitive substring) — use when the user names a grant - project_name: the project's title (case-insensitive substring) — disambiguates when grant names repeat - saved_grant_ids: budget ids (saved grant ids, prefix "save_") for exact budgets - transaction_date: an expense date (YYYY-MM-DD) — returns budgets whose award period covers it - budget_version_statuses: one or more of draft, activation_in_progress, active, archived — returns only budgets that have a version in those statuses, and lists only those versions under budget_versions (use ["draft"] to review drafts, ["archived"] for history; omit to see every version) Each budget's "id" is its saved grant id (prefix "save_") for use with other saved-grant tools, plus grant_name and project_title to identify it. A budget contains budget_phases (each phase is a time window such as a grant year), and each phase contains expense_categories nested as a tree (child_categories). Budgets can belong to grants in any status, not only awarded ones; saved_grant_status holds the grant's status (researching = "Researching", planned = "Planned", loi_in_progress = "LOI In Progress", loi_submitted = "LOI Submitted", started = "Application In Progress", submitted = "Application Submitted", funding_awarded = "Awarded - Active", closed = "Awarded - Closed", declined = "Declined", abandoned = "Abandoned"). When placing an expense, prefer awarded grants (funding_awarded or closed) and use transaction_date to narrow to budgets whose award period covers the expense. All amounts are integer cents (amount_currency holds the currency): - amount_cents: budgeted amount - actual_cents: spent so far (excludes planned and ignored expenses) - planned_cents: planned but not yet actual - remaining_cents: amount_cents - actual_cents - planned_cents (negative means over budget) Category amounts roll up the whole subtree, so a parent category's totals include its children's. To place an expense, match it to a category by name and prefer a budget/category whose remaining_cents can cover it. Each budget also lists all of its budget_versions: active first, then in-progress, then drafts, then archived. Each has an "id" (prefix "bv_"), name, status, description, effective_date, activated_at, archived_at and amount_budgeted_cents. The top-level budget_phases and amounts always describe the active version. A version that was never activated (a draft, or a version archived while still a draft) carries its proposed tree under draft_phases (phases → categories → subcategories, with amount_in_cents and funding_sources); versions that were activated have draft_phases null. Pass a draft's id as budget_version_id to `upsert_budget_versions` to replace it. A grant whose only versions are drafts or archived is listed with zero top-level amounts and no budget_phases, even if it is not yet awarded.
list_budgets
List the account's custom field definitions — the extra fields this organization has added to its saved grants and funders. Call this first whenever the user names a field that is not a built-in one ("Priority", "Program Area", "Internal Owner"). It is the only way to resolve such a name to a field and to learn what values that field can hold. Then pass include_custom_fields: true to list_saved_grants or list_funders to read the values themselves. Each definition returns: - name: what the user calls the field - attached_to: which record the field hangs off (SavedGrant, Funder) - value_type: one of string, text, date, amount, numeric, enum, multiselect, link - options: for enum and multiselect fields, the allowed choices, each with an option_key (stored), an option_value (shown to people) and a display_order Values read back from list_saved_grants and list_funders are option_value labels, not option_keys, so compare them against option_value. A multiselect value is those labels joined with ", ". Filters: - attached_to: SavedGrant, Funder — narrows to fields on saved grants or on funders With no filters, returns the account's custom fields a page at a time — page_size defaults to 20. If meta.has_more is true there are more definitions; page with the cursor before concluding a field does not exist.
list_custom_field_definitions
List the documents (`doc_...`) and document links (`encryptedcred_...`) in the account's Document Library. Pagination: - Every document is listed before any document link. - `page_size` counts documents and document links together. - `document_links` is empty until the last page of documents. After that, `documents` is empty. - While `meta.has_more` is true, call again with `cursor` to get the next page. Filters: - `search`: matches documents on title, file name, summary, extracted text and project title, and document links on name. - `purposes`: documents with these purposes. Returns documents only. - `extensions`: documents with these file extensions. Returns documents only. `public_url`: a document's `public_url` only opens for someone logged into Instrumentl with access to that document. Return the url to the user to open in their browser rather than fetching it.
list_documents
List the current user's expenses. At least one filter must be provided: - saved_grant_id: a SavedGrant api_id (prefix "sgrt_") - expense_ids: an array of Expense api_ids - project_name: a project title (case-insensitive substring); conditionally joins projects - grant_name: a grant name (case-insensitive substring); conditionally joins grants Filters compose with AND. project_name and/or grant_name resolve to the user's matching saved grants and return all expenses across them.
list_expenses
List the folders in the account's Document Library. Filter with `search` to filter by folder name.
list_folders
List all Funder Contacts
list_funder_contacts
List all Funders
list_funders
List all grants. This API will only return grants that match one of the following: 1. are custom for your user (created via a spreadsheet upload or custom grant form) 2. saved to a project 3. hidden from a project 4. hidden account-wide.
list_grants
List Instrumentl's recommended funders (Funder Matches) for a Project. A Funder Match is a whole funder, not one grant; for recommended grants, use `list_project_matches`. Each Funder Match has a `decision`: "saved" when the user saved a grant from that funder to this project, "hidden" when they hid one ("Not interested") from this project or from all projects, and "undecided" otherwise. Pass its `ein` to `list_funders` for the funder's details.
list_project_funder_matches
List Instrumentl's recommended Grants (Matches) from the public catalog for a Project. A Match is a suggested funder/grant the user has not yet decided on; it is separate from the user's tracker, which is a view of saved grants. Before calling this tool, disambiguate with the user when the wording could go either way. Users routinely say "my grants/matches/opportunities (for my project X)" to mean entries already in their tracker (SavedGrants → list_saved_grants), and other times to mean fresh recommendations from the catalog (Matches → this tool). Ask a short clarifying question, e.g.: "Do you mean grants/matches already saved in your tracker, or new recommendations Instrumentl has surfaced for this project?" Use this tool only after confirming the user wants recommendations; otherwise call list_saved_grants (it accepts `project_name` or `project_id`). Filters: - project_id: a Project api_id (prefix "proj_") to scope recommendations to that project - match_ids: array of Match api_ids
list_project_matches
List all projects associated with the current account
list_projects
List the user's SavedGrants — entries already in their tracker. A SavedGrant is the user's record of pursuing a Grant for a specific Project; an "awarded" SavedGrant is one with status "funding_awarded" or "closed". Each SavedGrant has a `status` (the machine value — use it for the `statuses` filter and for update_saved_grant) and a `status_label` (the label the user sees in their tracker). Always use `status_label` when describing a status to the user; never show them the raw `status` value. Before calling, disambiguate when the wording is ambiguous; ask a single clarifying question rather than guessing. The most common confusion is between SavedGrants (already in the tracker) and Matches (new recommendations from the public catalog). A good clarifier: "Do you mean grants/matches already in your tracker, or new recommendations Instrumentl has surfaced for this project?" - "my grant(s)", "my match(es)", "my opportunity/opportunities", "grants for my project X", "what have I saved/tracked": almost always SavedGrants already in the tracker → THIS tool. If the phrasing could plausibly mean "new recommendations" instead, confirm with the user first; use list_project_matches only after they confirm they want recommendations. - "awards", "current grants", or bare "grants" in an award/funding context: awarded SavedGrants → THIS tool with `awarded: true` (matches both "Awarded - Active" and "Awarded - Closed"). For only currently-active awards, pass `statuses: ["funding_awarded"]` instead. - "find grants", "search grants", "what grants are available": the public Grant catalog → use list_grants. - Bare "grants" with no "my" and no award context: ambiguous — ask first. Filters (compose with AND): - saved_grant_id: a SavedGrant api_id (prefix "save_") — returns just that one - project_id / grant_id / funder_id: api_ids to scope by the related record - statuses: array of SavedGrant status values. Map the tracker label the user names to its value: researching = "Researching", planned = "Planned", loi_in_progress = "LOI In Progress", loi_submitted = "LOI Submitted", started = "Application In Progress", submitted = "Application Submitted", funding_awarded = "Awarded - Active", closed = "Awarded - Closed", declined = "Declined", abandoned = "Abandoned" - awarded: true restricts to awarded SavedGrants; false excludes them - award_year: integer fiscal year for the award period - project_name: case-insensitive substring on the project title (use when the user names a project) - grant_name: case-insensitive substring on the underlying grant's name (use when the user names a grant) - submission_goal_gte / submission_goal_lte: ISO dates (YYYY-MM-DD); keeps saved grants with a submission goal date in the range (either bound may be omitted) - submission_goal_submitted: false keeps saved grants with a goal not yet marked submitted (no submitted_at); true keeps those with a goal marked submitted. When combined with the date range, the same goal must match both Submission goals: each saved grant carries a `submission_goals` array holding the goals for the funding cycle it currently tracks (goals left on other cycles' deadlines are omitted). Each entry's `submission_goal` is the date the user plans to submit (their target/goal date for that deadline) and `submitted_at` is when they actually submitted; `deadline_id` ties it to the funder deadline it was set against, and `deadline_name` says which deadline of the cycle it is (letter_of_inquiry, pre_proposal, full_proposal, or null when unnamed or not tied to a funder deadline). Use these to answer "when are we planning to submit" or "what are our submission goals" questions — do not infer them from the Grant's funding cycles. Deadline questions ("what's due this month?", "what are we submitting next quarter?"): pass the date range plus `statuses` limited to the in-progress ones (planned, started, loi_in_progress, loi_submitted), and add submission_goal_submitted: false to drop goals already marked submitted (e.g. the LOI on an loi_submitted grant). Rely on status first: submitted_at is often left blank after a grant is submitted, and some older goals carry a submitted_at that was never real. Only the matching goals' saved grants are filtered — each returned saved grant still lists all of its submission goals, so check each goal's date when answering. Custom fields: set include_custom_fields to true to get each saved grant's custom field values. Call list_custom_field_definitions first to learn which fields the account has and what their options are. Values come back as labels, not option keys, so compare them against a definition's option_value. By default only records currently in the user's tracker are returned. Records the user hid / marked "Not interested" are kept as history; pass include_hidden: true to see them, e.g. when the user asks about a grant they previously dismissed. To list everything in the user's tracker, call with no filters.
list_saved_grants
List the AI-generated answer snippets of a grant application, grouped by application question. Pass the `application_id` returned by `generate_snippets`. Snippets are generated asynchronously: `meta.status` is the application's generation status (`in_progress` means more snippets may still arrive; `completed` means the run has finished). Only questions that already have at least one snippet are returned, so an empty list while `in_progress` just means nothing has been generated yet — check again later rather than restarting generation. Each snippet carries the `answer` text and its `sources`: the documents, grants or funders it was drawn from. An empty `sources` list means the answer was synthesized from the application's documents without a specific citation. Pass `question_ids` (the `id`s from `list_application_questions`) to only return snippets for those questions.
list_snippets
List the user's Tasks (also called custom grant deadlines). A Task belongs to a SavedGrant in the user's tracker and can have an assignee, a nominator, a creator, and (when done) a completer. DISAMBIGUATE before filtering by a person. The tool exposes four separate people filters — `assignee`, `nominator`, `created_by`, `completed_by` — because each captures a different relationship and they AND-compose, so picking the wrong one returns wrong results. When the user names a person without a clear role ("Sarah's tasks", "tasks for Sarah", "what is Sarah working on"), ask which they mean before calling. A good single clarifier: "Do you mean tasks assigned to Sarah, tasks she created, tasks she completed, or tasks she nominated (handed off)?" Common phrasings → likely role: - "my tasks", "Sarah's tasks", "tasks for Sarah", "what is Sarah working on": almost always `assignee` — confirm and proceed. - "tasks Sarah added/made/wrote": `created_by`. - "tasks Sarah finished/completed/closed out": `completed_by` (also implies done). - "tasks Sarah handed off / reassigned / passed to someone else": `nominator`. If unclear, ask before guessing. Each people filter matches first name, last name, OR email (case-insensitive substring), so the user need not say which form they remember. Other filters (compose with AND): - saved_grant_id / project_id: api_ids — use when you already have the id (e.g. from another tool call) - project_name / grant_name / funder_name: case-insensitive substrings — use when the user names the entity - assignee_id / nominator_id: user api_ids — for an exact person rather than a name search - is_done: true returns completed tasks; false returns open tasks ("show open tasks" is the most common ask) - past_due: true returns overdue, not-done tasks; false excludes them - unassigned: true returns tasks with no assignee (use for "tasks nobody owns") - kinds: array of task kinds (full_proposal, report, general, letter_of_inquiry, cultivation, application, payment_request, contract_agreement, site_visit, communications, event, other) - deadline_gte / deadline_lte: ISO dates; deadline_gte INCLUDES tasks with no deadline, deadline_lte does not Call with no filters to list every task in the user's tracker.
list_tasks
List the users (teammates) on the current account. Use this when the user references a teammate by name and you need their `id` to pass into another tool — `assignee_id` / `nominator_id` on ListTasks, `user_id` on ListProjects, owner / created-by filters on saved grants, etc. All those tools key off a user api_id (`user_...`), not an email or name. Filters (compose with AND): - search: case-insensitive substring match across first_name, last_name, and email — the workhorse for resolving "John Williams", "john@", or a partial name to a user - email: exact-match email lookup — use only when you already have the full email With no filters, returns every user on the account.
list_users
Request an application form for a grant already saved in the user's tracker, or check the status of an existing request. Use `list_saved_grants` to find the SavedGrant and pass its `id` as `saved_grant_id`. If the grant has not been saved yet, call `save_match` first and use the SavedGrant `id` it returns. Never guess an id. Do not use this tool for custom grants. Direct the user to request a custom grant's application form in the Instrumentl UI. The funding cycle is selected automatically: the cycle chosen on the saved grant if its deadline is still in the future, otherwise the grant's next upcoming cycle. Rolling grants have no funding cycle and need nothing extra. The call fails if the grant is not rolling and has no upcoming cycle, for example an opportunity whose cycles have all closed. This tool is idempotent. Call it again with the same arguments to check the current status. Status meanings: - `not_started`: no request has been made - `in_progress`: a request has been made - `live`: the application is ready to start - `cannot_be_built`: the application form cannot be built Each account can make up to 10 application form requests through MCP per calendar month, resetting on the first at 00:00 UTC. Checking an existing request's status or accessing an already-live form does not count toward this limit.
request_application_form
Save a grant match to a project. Defaults to saving to the project the match belongs to; pass `target_project_id` to save the grant to a different project in the same account. Pass `hide: true` to instead hide ("not interested") the match, so it no longer appears in the project's matches. This is reversible in the Instrumentl app. `target_project_id` is ignored when hiding. Each call creates a new SavedGrant. To remove a grant you previously saved, use the `hide_saved_grant` tool with the SavedGrant id returned here.
save_match
Send a feedback message from the user to the Instrumentl engineering team. Call this only when one of the following is clearly true: - The user has explicitly asked to report a bug, request a feature, or send feedback to the team. - You have already attempted to help with the user's actual task, and the user is still blocked or has expressed unresolved frustration that cannot be solved inside this conversation. DO NOT call this: - Proactively, on the first sign of frustration. Try to help first. - When the user is merely unsure how to do something -- answer the question instead. - More than once per conversation, unless the user explicitly asks to send another message. Before calling, do both of these with the user (do not guess either): 1. Confirm the wording of the `message` -- the team only sees what is passed here. 2. Ask which `category` best fits (bug / feature_request / complaint / other). Do not infer the category yourself unless the user has clearly stated it. The submission is delivered asynchronously to a private Slack channel monitored by engineering and product. There is no follow-up channel here, so do not promise a reply on a specific timeline.
submit_feedback
Rename and/or move Document Library folders. Pass up to 5 entries in `folders`. - folder_id: API ID (prefixed `folder_`) for a folder being updated. - name: (optional) A new name for the folder. Omit to keep it unchanged. - parent_folder_id: (optional) API ID (prefixed `folder_`) for the folder's new parent folder. Omit to keep it unchanged. Use `parent_folder_id: null` to move the folder to the root. Notes: - A moved folder's subfolders, documents and credentials move with it. - This tool call is all-or-nothing. If any entry fails, nothing is changed. - To update more than 5 folders at once, call this tool again. - An entry with neither the `name` nor `parent_folder_id` param is ignored. Use `list_folders` to find folder ids.
update_folders
Update fields on a saved (tracked) grant. Pass the SavedGrant's `id` (e.g. `save_...`) plus only the fields you want to change - omitted fields are left untouched. Updatable fields: - `status`: where the grant is in the pipeline. Users name it by its tracker label (e.g. "Application Submitted"); send the matching value (e.g. `submitted`). The response's `status_label` is what to show the user. - `notes`: free-form notes about the opportunity. - `amount_requested` / `amount_awarded`: dollar amounts. - `year`: fiscal year the grant is tracked under. - `notified_at`, `award_period_start_date`, `award_period_end_date`: dates relevant once a grant is awarded. - `owner_id`: the User (`user_...`) to make responsible for the grant, or null to clear the owner. - `project_id`: move the grant to a different project (`proj_...`). Notes: - Setting `status` to `researching` clears the requested amount and submission goals, matching the app's behavior. - To stop tracking a grant, use `hide_saved_grant` instead. Use `list_saved_grants` to find the `saved_grant_id`.
update_saved_grant
Upload one or more documents to the account's document library, optionally attaching them to saved grants and tasks. Each document requires `data_base64` containing strict base64-encoded file contents (without a data-URL prefix) and `filename` including its extension. `title` is an optional custom title. If you want to associate any of the documents with saved grants, use the `list_saved_grants` tool to find saved grants and pass their `id` values in each document's `saved_grant_ids`. If you want to attach any of the documents to tasks, use the `list_tasks` tool to find tasks and pass their `id` values in each document's `task_ids`. IMPORTANT: The document will also be associated with each task's saved grant. Each document may include a `folder_id` to select its destination folder. Omit it on a document to upload that file to the library root. Allowed filename extensions (case-insensitive): pdf, docx, doc, png, jpg, jpeg, csv, xlsx, xls. Upload limits are 25 MB per file and 30 MB total, measured using decoded file sizes. Each document is uploaded independently. If one fails (eg: an unsupported file type, a file over the size limit, or a saved grant, task, or folder that can't be found or accessed), it is marked `failed` and the rest can still upload. Only a batch over the total size limit rejects the whole request. This tool is not idempotent. Repeating a successful upload creates another document; do not retry successful items. Each document returns its original input filename, a status, and an errors array. The returned filename matches the input even if storage sanitizes it. Successful documents also return their `id`, prefixed `doc_`, which other document tools accept. Status meanings: - `success`: the file and requested associations were saved, errors is empty, and `id` is set. - `failed`: the document could not be uploaded, errors contains an explanation.
upload_documents
Create new tasks and/or update existing tasks in a single best-effort call. Each row in `tasks` is either: - { "op": "create", "saved_grant_id": "save_...", "kind": "...", ...optional fields } - { "op": "update", "id": "task_...", ...fields to change } Rows are processed independently — a failed row does not roll back the others. Use `op: "create"` to add a task to a SavedGrant. `saved_grant_id` and `kind` are required; the calling user becomes the creator and nominator. Use `op: "update"` to change an existing task. Only `id` is required; pass any subset of mutable fields. Pass `done_at` as a timestamp to mark the task complete, or `null` to reopen it. Available kinds: full_proposal, report, general, letter_of_inquiry, cultivation. Resolving a user for `assignee_user_id` or `notify_user_ids`: these must be `user_...` API IDs. If the user names someone by first name, last name, or email, call `list_users` to resolve the API ID first. Do not try to find users via `list_tasks` people filters — those only surface users who already appear on a task, not every member of the account. The response shape is: { "results": [ { "index": 0, "op": "create", "status": "ok", "task": { ... } }, { "index": 1, "op": "update", "status": "failed", "reason": "not_found" } ], "created_count": N, "updated_count": N, "failed_count": N } Each result's `index` matches the input row at the same position. Possible failure reasons: - "not_found": task id doesn't exist or belongs to a different account (update) - "saved_grant_not_found": saved_grant_id doesn't exist or belongs to a different account (create) - "user_not_found": assignee_user_id or notify_user_ids contains a user not in this account - "not_authorized": the caller lacks permission for this row - "invalid": validation failed; see `errors`
upsert_tasks
Instrumentl ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Instrumentl's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Instrumentl alternatives on ChatGPT?
As of 2026-10-25, Instrumentl competes with AltEditais, Ausschreibungsagenten.de, Bidaya, BidPrime, Carabela – Public tenders, Civic Marketplace, CLEATUS, DC PASS Contracts and 35 more in ChatGPT Government Procurement & Contract Search, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.