# Connect with ChatGPT
Source: https://docs.civicmarketplace.com/ai-connector/connect-chatgpt
Add the CivicMarketplace AI Connector to ChatGPT as a custom connector
Connect CivicMarketplace to [ChatGPT](https://chatgpt.com) so you can search contracts and suppliers right inside your conversations.
Custom connectors are available on **ChatGPT Plus, Pro, Business, Enterprise, and Edu** plans. On
Business, Enterprise, and Edu, a workspace administrator may need to enable custom connectors
first.
The endpoint you'll use:
```
https://mcp.civicmarketplace.com/mcp
```
Enter the URL exactly as shown, including the `/mcp` at the end. A bare domain (without `/mcp`)
will not connect.
## Add the connector
In ChatGPT, go to **Settings → Connectors** (you may find custom connectors under an **Advanced**
or **Developer mode** toggle depending on your plan).
Click **Create** / **Add custom connector** and fill in:
* **Name**: `CivicMarketplace`
* **MCP Server URL**: `https://mcp.civicmarketplace.com/mcp`
* **Authentication**: OAuth (selected automatically)
Click **Connect**. A CivicMarketplace sign-in page opens — log in with your normal account and
approve the requested permissions. You'll be returned to ChatGPT once it's connected.
Start a new chat. Enable the CivicMarketplace connector for the conversation (via the **+** /
tools menu), then ask something like *"Find CivicMarketplace suppliers in Texas with cybersecurity certifications."*
## Troubleshooting
Double-check the URL is exactly `https://mcp.civicmarketplace.com/mcp` (with `https://` and the
trailing `/mcp`). If it still fails, remove the connector and add it again.
This is usually a stale session. **Disconnect** the connector completely, then add it again and
sign in fresh.
Make sure the connector is turned on for the current chat in the tools menu, and reference
CivicMarketplace explicitly in your prompt (e.g. *"Using CivicMarketplace, …"*).
Custom connectors require a supported plan, and on managed workspaces they may be disabled by
your administrator. Ask your workspace admin to enable custom MCP connectors.
## Next steps
See what you can ask once you're connected.
Review the MCP tools and required permissions.
# Connect with Claude
Source: https://docs.civicmarketplace.com/ai-connector/connect-claude
Add the CivicMarketplace AI Connector to Claude.ai, Claude Desktop, or Claude Code
Connect CivicMarketplace to [Claude](https://claude.ai) and ask about contracts and suppliers directly in your conversations.
Custom connectors are available on **Claude Pro, Max, Team, and Enterprise** plans. On Team and
Enterprise, an administrator may need to enable connectors for the organization first.
The endpoint you'll use:
```
https://mcp.civicmarketplace.com/mcp
```
## Claude.ai (web)
Go to **Settings → Connectors** and click **Add custom connector**.
* **Name**: `CivicMarketplace`
* **URL**: `https://mcp.civicmarketplace.com/mcp`
Click **Add**.
Click **Connect**. A CivicMarketplace sign-in window opens — log in with your normal account and
approve the requested permissions.
In a new chat, open the tools/connectors menu and confirm CivicMarketplace is enabled. Then ask
something like *"Search CivicMarketplace for janitorial contracts."*
## Claude Desktop
Open **Settings → Connectors**. You'll see your existing connectors grouped under **Web** and
**Desktop**.
Click the **+** button at the top of the Connectors panel, then choose **Add custom connector**
from the menu.
* **Name**: `Civic Marketplace`
* **URL**: `https://mcp.civicmarketplace.com/mcp`
Click **Add**.
Click **Connect**. A CivicMarketplace sign-in window opens — log in with your normal account and
approve the requested permissions. The connector will then appear under **Web** and show a
**Disconnect** button once it's linked.
Open the connector to see its **Tool permissions**. CivicMarketplace tools include read tools and
scoped write tools; each can be set to **Allow**, **Needs approval** (the default), or
**Disallow**. Leaving them on *Needs approval* means Claude asks before each use.
## Claude Code (CLI)
```bash theme={null}
claude mcp add --transport http civicmarketplace https://mcp.civicmarketplace.com/mcp
```
This only registers the server — it does **not** sign you in yet. `claude mcp list` will show it
as `! Needs authentication`, which is expected at this point.
Authentication doesn't happen from `claude mcp add` or `claude mcp list` — it happens inside an
interactive session. Start Claude Code:
```bash theme={null}
claude
```
Then run the `/mcp` command, select **civicmarketplace**, and choose **Authenticate**. Your
browser opens the CivicMarketplace sign-in page — log in and approve the requested permissions, then
return to the terminal.
Still in the session, run `/mcp` again — civicmarketplace should now show as connected. From a
fresh terminal you can also check:
```bash theme={null}
claude mcp list
```
It should now read `civicmarketplace: … - ✓ Connected`.
`claude mcp list` only **reports** status — it never opens the login window. If a server shows `!
Needs authentication`, run `/mcp` inside `claude` to sign in.
## Troubleshooting
Make sure pop-ups are allowed for Claude, and that you're signing in with the same email you use
for CivicMarketplace. If you recently changed your access, disconnect and reconnect the
connector to refresh your session.
Confirm the connector is toggled on for the current chat (in the tools/connectors menu), then
try again. Custom connectors must be enabled per conversation in some clients.
The connector only returns data your CivicMarketplace account can access. If you expect to see
something you can't, contact your account manager — your account may need additional access in
CivicMarketplace itself.
## Next steps
See what you can ask once you're connected.
Review the MCP tools and required permissions.
# Connect with Microsoft Copilot
Source: https://docs.civicmarketplace.com/ai-connector/connect-microsoft-copilot
Add the CivicMarketplace AI Connector to Microsoft 365 Copilot
Connect CivicMarketplace to **Microsoft 365 Copilot** so your team can ask about contracts and suppliers from inside Copilot.
Adding an MCP connector to Microsoft 365 Copilot is done through **Copilot Studio** and typically
requires a Microsoft 365 Copilot license plus permission to build or publish agents in your
tenant. Check with your Microsoft 365 administrator if you don't have access.
The endpoint you'll use:
```
https://mcp.civicmarketplace.com/mcp/copilot
```
## Add the connector in Copilot Studio
Go to [copilotstudio.microsoft.com](https://copilotstudio.microsoft.com) and open (or create)
the agent you want to extend.
In the agent, go to **Tools → Add a tool → Model Context Protocol** (or **New tool → MCP**), and
enter the server URL `https://mcp.civicmarketplace.com/mcp/copilot`.
Choose **OAuth** authentication. Copilot Studio uses CivicMarketplace as the identity provider —
users sign in with their own CivicMarketplace account and approve the requested permissions the
first time they use the connector.
Save and publish the agent. In Copilot, ask the agent something like *"Search CivicMarketplace
for HVAC contracts."* The first request prompts each user to sign in.
Each user authenticates as themselves, so results are always scoped to what that person's
CivicMarketplace account can access — no shared credentials.
## Troubleshooting
MCP support and the exact menu names roll out gradually across tenants and may require specific
licensing. Make sure your tenant has Copilot Studio enabled and you have rights to add tools to
agents.
Confirm the tool's authentication is set to OAuth (not "no authentication"). Re-publish the
agent after changing authentication settings.
The connector only returns data a user's CivicMarketplace account can access. If a user expects
more, their CivicMarketplace access may need to be updated — contact your account manager.
## Next steps
See what you can ask once you're connected.
Review the MCP tools and required permissions.
# Example Prompts
Source: https://docs.civicmarketplace.com/ai-connector/example-prompts
Things you can ask once the CivicMarketplace AI Connector is connected
Once you've [connected your assistant](/ai-connector/overview), you can ask questions in plain English. Here are prompts that map to what the connector can do.
If your assistant doesn't reach for CivicMarketplace automatically, name it explicitly — e.g.
*"Using CivicMarketplace, find…"*.
## Finding contracts
* "Search CivicMarketplace for janitorial services contracts."
* "Find cooperative contracts for water treatment chemicals."
* "What IT consulting contracts are available through Sourcewell?"
* "Show me contracts related to fleet vehicles and summarize each in one line."
* "If CivicMarketplace has no fleet-management contract, search the approved external procurement sources."
* "Search outside CivicMarketplace for a cooperative agreement covering public-safety radios."
* "Open the NPPGov agreement from those external results, summarize its parties, term, and scope, and cite the physical PDF page for each claim."
When a keyword search finds no CivicMarketplace contract, the connector can continue across 101 approved public procurement sources. It can read supported PDF, HTML, and plain-text documents linked by those results. External results and extracted text are labeled as public evidence and are not verified CivicMarketplace records.
## Contract detail and documents
* "Give me the full details of the office supplies contract — value, term, and status."
* "Who are the awarded suppliers on contract 63?"
* "Open the pricing sheet on that contract and tell me the unit prices for copy paper."
* "Summarize the master service agreement attached to this contract."
* "Does this contract's RFP mention cybersecurity requirements?"
## Discovering suppliers
* "Find cybersecurity suppliers based in or serving Texas." (free-text + state filter)
* "Which suppliers are DBE-certified?" (SBE certification filter)
* "Show me MBE and WOSB suppliers in California." (multiple certifications + state)
* "List suppliers with an ISO 37001 certification." (technical certification filter)
* "What certifications can I filter suppliers by?" (lists the available certifications)
* "Look up Acme Tech Solutions and show me their certifications and contact info."
* "List suppliers offering IT services." (filter by service category)
Certification filtering covers **both** families the directory tracks: **SBE/diversity**
certifications (DBE, MBE, HUB, WOSB, SMBR…) and **technical** certifications (ISO 37001, AZ-104,
A+…). Ask the assistant to list certifications if you're unsure of the exact name.
## Counts and summaries
* "How many active contracts does my agency have access to?"
* "How many suppliers offer IT services?"
* "Compare the suppliers on these two contracts."
## Agency workflows
* "Show the status summary for my quick quote and cooperative quote requests."
* "Create a quick quote request for computer software suppliers with a deadline 30 days from today."
* "Show my waiting quick quote requests and summarize supplier response counts."
* "Archive quick quote request 42."
* "How many unread CivicMarketplace inbox conversations do I have?"
* "Read the latest messages in inbox conversation 91 and draft a short reply."
## Supplier workflows
* "Show the status summary for quote requests sent to my supplier account."
* "Show me quick quote and cooperative quote requests sent to my supplier account."
* "Pull the details for supplier coop quote request 21."
* "Submit a response to quick quote request 56 with an estimate of \$12,500."
* "Decline coop quote request 21 because we cannot meet the deadline."
* "Show my supplier inbox conversations with unread messages."
* "Reply to conversation 91 and thank the agency for the clarification."
* "Update my supplier availability to available."
* "Show my supplier dashboard keywords, certifications, and NIGP capacity categories."
* "Find available supplier keywords matching cybersecurity, then add the best matches to my profile."
* "Add NIGP capacity codes for software and IT services to my supplier profile."
* "Remove Budget Systems from my supplier dashboard keywords."
* "List my supplier references and reference requests."
* "Send a reference request to [procurement@example.com](mailto:procurement@example.com)."
* "Show solicitations available to my supplier account and register intent to bid on solicitation 12."
* "Who is on my supplier team?"
## Admin workflows
* "Search admin suppliers for Acme and show the matching record IDs."
* "Create a supplier profile for this company metadata."
* "Add NIGP codes 208 and 209 to supplier 123."
* "Update contract 63 to published."
* "Replace the city services on contract 63 with these IDs."
## Refining with reference data
* "What service categories are available in CivicMarketplace?"
* "List the cooperatives I can filter by."
* "Show me lead entities so I can narrow my search."
## Good to know
The connector exposes only the tools your account type and approved OAuth scopes allow.
You only ever see data your own CivicMarketplace account is allowed to access.
Document reading works on contracts whose documentation is marked public and that you're
authorized to view. External reading is limited to approved public procurement domains.
Some assistant clients ask before write tools create records, send messages, archive requests,
or update admin data.
Results include direct links back to CivicMarketplace so you can verify and dig deeper.
# AI Connector Overview
Source: https://docs.civicmarketplace.com/ai-connector/overview
Bring CivicMarketplace data and workflows into ChatGPT, Claude, and Microsoft Copilot
The CivicMarketplace **AI Connector** lets you query cooperative contracts, suppliers, documents, agency quote requests, supplier dashboard workflows, inbox messages, and admin records from inside the AI assistant you already use — ChatGPT, Claude, or Microsoft Copilot — in plain English. No code, no API keys.
It's built on the [Model Context Protocol (MCP)](https://modelcontextprotocol.io), an open standard for connecting AI assistants to external tools and data. You connect once, sign in with your CivicMarketplace account, and your assistant can use approved CivicMarketplace tools on your behalf.
The connector only sees and changes data your own CivicMarketplace account is allowed to access.
Write tools require explicit OAuth permissions such as `quote-requests:write`, `inbox:write`,
`supplier-profile:write`, `suppliers:write`, or `admin:write`.
## What you can do
Find cooperative contracts by keyword, cooperative, supplier, service category, or recent
updates, then search approved public procurement sources when no marketplace match exists.
Pull full detail — description, value, term dates, status, suppliers, lead entity, NIGP codes,
and the list of attached documents.
Summarize and answer questions about the actual text of public contract files — RFPs, pricing
sheets, master service agreements, and approved external PDF or HTML sources.
Search the supplier directory and pull full profiles, including contact info, certifications,
and verification status.
Ask "how many" questions and refine with service categories, cooperatives, and lead entities.
For agency users, create quote requests, check request status, read inbox messages, and reply to
conversations when permitted.
For supplier users, view quote requests sent to your supplier account, reply from your inbox,
update supplier dashboard profile information, manage media, references, solicitations, and team
members when permitted.
For CivicMarketplace admins, search, create, and update suppliers, agencies, cooperatives,
contracts, statuses, and relationships.
Marketplace records link back to CivicMarketplace; external discoveries link to their public
procurement source and are clearly labeled.
## How it works
```text theme={null}
You ──ask──► AI assistant ──► CivicMarketplace AI Connector ──► CivicMarketplace
(signs you in via OAuth) (your scoped data)
```
1. You add the connector to your assistant once, using the endpoint below.
2. Your assistant opens a CivicMarketplace sign-in page. You log in with your normal account and approve the requested permissions.
3. From then on, you can ask questions and the assistant retrieves live marketplace data, automatically scoped to what your organization can see.
## Endpoint
Add this URL when connecting your assistant:
```
https://mcp.civicmarketplace.com/mcp
```
## Prerequisites
* A CivicMarketplace account (the same login you use for the web app).
* An AI assistant that supports custom MCP connectors — see the per-assistant guides below for supported plans.
## Connect your assistant
Claude.ai, Claude Desktop, and Claude Code.
Custom connectors in ChatGPT.
Microsoft 365 Copilot agents.
## AI Connector vs. Partner API
Both expose the same CivicMarketplace data — pick based on who's using it.
| | **AI Connector (MCP)** | **[Partner API](/introduction)** |
| - | - | - |
| **For** | People, inside an AI assistant | Developers, inside applications |
| **Auth** | Sign in with your CM account (OAuth) | API key (`cmp_live_…`) |
| **Access** | Scoped read and write tools, depending on approved OAuth permissions | Read-only |
| **Setup** | Add a connector URL | Write code against REST endpoints |
## Useful links
See what you can ask once connected.
Review the MCP tools and required permissions.
Don't have a CivicMarketplace account yet?
# Tools and Permissions
Source: https://docs.civicmarketplace.com/ai-connector/tools-and-permissions
What the CivicMarketplace AI Connector can do, and which permissions each workflow requires
The CivicMarketplace AI Connector exposes MCP tools for marketplace and approved public-source search, contract document reading, agency quote workflows, supplier dashboard workflows, inbox messaging, supplier creation, and admin maintenance.
Every tool is scoped to the signed-in CivicMarketplace user. Your assistant can only use tools allowed by your account type, organization access, and the OAuth permissions you approved.
## Permission model
| Permission | Enables |
| - | - |
| `contracts:read` | Search, count, and read contract details and supported public contract documents. |
| `suppliers:read` | Search, count, and read supplier profiles. |
| `suppliers:write` | Create suppliers. Supplier creation is limited to CivicMarketplace internal admin users. |
| `quote-requests:read` | Read agency quick quote and cooperative quote request status. |
| `quote-requests:write` | Create, archive, unarchive, cancel, reassign agency quote requests, or respond to supplier quote requests. |
| `inbox:read` | Read agency or supplier inbox conversation summaries and messages. |
| `inbox:write` | Send inbox replies and mark conversations read. |
| `team:read` | Read agency handoff colleagues or supplier team members/invites. |
| `team:write` | Manage supplier teammates when the signed-in supplier user is allowed to do so. |
| `supplier-profile:read` | Read the signed-in supplier's dashboard profile, addresses, keywords, certifications, and capacity. |
| `supplier-profile:write` | Update the signed-in supplier's dashboard profile, addresses, keywords, certifications, and capacity. |
| `supplier-media:read` | Read supplier dashboard catalogs, website links, and videos. |
| `supplier-media:write` | Manage supplier dashboard catalogs, website links, and videos. |
| `supplier-references:read` | Read supplier references and reference request status. |
| `supplier-references:write` | Send supplier reference requests. |
| `supplier-solicitations:read` | Read solicitations available to the signed-in supplier. |
| `supplier-solicitations:write` | Register intent to bid and ask solicitation questions. |
| `supplier-analytics:read` | Read supplier dashboard analytics and profile completeness. |
| `supplier-signals:read` | Read the Signals opportunities matched to the signed-in supplier. |
| `admin:read` | Use admin search and detail tools for suppliers, agencies, cooperatives, and contracts. |
| `admin:write` | Create and update admin records, status, and relationships. |
## Marketplace read tools
| Tool | What it does |
| - | - |
| `search_contracts` | Searches contracts by keyword, cooperative, supplier, service category, or update time. |
| `get_contract` | Returns full contract details, suppliers, lead entity, cooperative, dates, value bracket, NIGP codes, and document metadata. |
| `read_contract_document` | Reads extracted text chunks from supported contract documents: PDF, XLSX, CSV, and plain text. |
| `count_contracts` | Returns only the number of contracts matching a filter. |
| `search_suppliers` | Searches suppliers by keyword, state, certification, service category, or update time. |
| `get_supplier` | Returns full supplier profile details, contact info, certifications, served states, and source link. |
| `count_suppliers` | Returns only the number of suppliers matching a filter. |
## External public-source search
| Tool | What it does |
| - | - |
| `search_external_contracts` | Searches 101 approved public procurement sources after a keyword search finds no CivicMarketplace contracts, or when you explicitly request it. |
| `read_external_contract_document` | Reads paginated text from a PDF, HTML page, or plain-text URL returned by external search, with physical page markers for PDFs. |
These read-only tools are available to every signed-in connector user and do not require an additional OAuth permission. External document reading is restricted to the configured public-procurement source inventory and applies download, redirect, file-size, and network-address safeguards. Extracted PDFs include one-based physical page markers so the assistant can cite the page supporting each claim. Results and extracted text are external public evidence, not imported or verified CivicMarketplace records. Your assistant should preserve that distinction when presenting them.
## Reference data
| Tool | What it does |
| - | - |
| `list_lead_entities` | Lists lead entities that own contracts. |
| `list_coops` | Lists purchasing cooperatives available to the caller. |
| `list_city_services` | Lists service categories used by contracts and suppliers. |
| `search_nigp_codes` | Searches NIGP categories by plain-language purchasing need or class number. |
| `list_certifications` | Lists SBE/diversity and technical certifications available for supplier filtering. |
## Supplier creation
| Tool | What it does |
| - | - |
| `create_supplier` | Creates one supplier profile, including metadata, certifications, categories, regions, NIGP codes, domains, and whitelisted emails. |
| `bulk_create_suppliers` | Creates suppliers from CSV text after validating every row. If any row is invalid, no suppliers are created. |
Supplier creation is metadata-only. It does not upload binary logo, catalog, insurance, or W-9
files; pass existing S3 keys where supported.
## Agency quote requests
| Tool | What it does |
| - | - |
| `search_quick_quote_suppliers` | Finds suppliers the agency can invite, from a plain-language need, a name, or NIGP categories. |
| `list_coop_quote_suppliers` | Lists a contract's suppliers that are active on it this quarter and can be invited. |
| `create_quick_quote_request` | Creates a quick quote request for the authenticated agency and sends normal supplier notifications. |
| `bulk_create_quick_quote_requests` | Creates quick quote requests from CSV text after all rows validate. |
| `create_coop_request` | Creates a direct cooperative contract quote request for selected suppliers on a contract. |
| `bulk_create_coop_requests` | Creates cooperative quote requests from CSV text after all rows validate. |
| `list_quick_quote_requests` | Lists the authenticated agency's quick quote requests. |
| `list_coop_quote_requests` | Lists the authenticated agency's cooperative quote requests. |
| `get_quick_quote_request` | Reads one quick quote request with owner, status, suppliers, and response counts. |
| `get_coop_quote_request` | Reads one cooperative quote request with owner, status, suppliers, and response counts. |
| `get_quote_request_status_summary` | Summarizes quick and cooperative quote request statuses. |
| `change_quick_quote_owner` | Changes ownership for one quick quote request when the caller has permission. |
| `change_coop_quote_owner` | Changes ownership for one cooperative quote request when the caller has permission. |
| `archive_quick_quote_requests` | Archives selected quick quote requests. |
| `unarchive_quick_quote_requests` | Restores selected quick quote requests. |
| `archive_coop_quote_requests` | Archives selected cooperative quote requests. |
| `unarchive_coop_quote_requests` | Restores selected cooperative quote requests. |
| `cancel_quick_quote_request` | Permanently cancels one waiting quick quote request. |
| `cancel_coop_quote_request` | Permanently cancels one waiting cooperative quote request. |
## Agency inbox
| Tool | What it does |
| - | - |
| `get_inbox_unread_count` | Returns the authenticated user's unread conversation count. |
| `list_inbox_conversations` | Lists agency or supplier inbox conversations, optionally unread only. |
| `get_inbox_messages` | Reads messages in one inbox conversation. |
| `send_inbox_message` | Sends a reply in one inbox conversation. Attachments must reference existing S3 metadata. |
| `mark_inbox_conversation_read` | Advances the read cursor for one inbox conversation. |
## Supplier quote requests
These tools are for signed-in supplier users. They only show quote requests sent to the authenticated supplier account.
| Tool | What it does |
| - | - |
| `list_supplier_quick_quote_requests` | Lists quick quote requests sent to the authenticated supplier. |
| `list_supplier_coop_quote_requests` | Lists cooperative quote requests sent to the authenticated supplier. |
| `get_supplier_quick_quote_request` | Reads one supplier-side quick quote request with agency, deadline, status, and response details. |
| `get_supplier_coop_quote_request` | Reads one supplier-side cooperative quote request with contract, agency, deadline, and status. |
| `get_supplier_quote_request_status_summary` | Summarizes supplier-facing quote statuses such as new, replied, awarded, declined, and expired. |
| `submit_supplier_quick_quote` | Submits a supplier response to one quick quote request. Attachments must use existing S3 metadata. |
| `submit_supplier_coop_quote` | Submits a supplier response to one cooperative quote request. |
| `decline_supplier_quick_quote` | Declines one quick quote request with a reason. |
| `decline_supplier_coop_quote` | Declines one cooperative quote request with a reason. |
## Supplier dashboard profile
These tools operate on the signed-in supplier's own dashboard profile. They never accept a `supplier_id`.
| Tool | What it does |
| - | - |
| `get_my_supplier_profile` | Reads the supplier dashboard profile, including services, certifications, addresses, capacity, media, and references. |
| `update_my_supplier_profile` | Updates top-level profile fields such as company name, intro, website, contact info, and availability status. |
| `list_supplier_profile_options` | Lists lookup options for profile updates: states, keywords, certifications, and internal NIGP option IDs. |
| `set_supplier_states_served` | Replaces the full set of states served. |
| `set_supplier_services_certifications` | Replaces supplier keywords and/or certifications. Use add/remove tools for normal incremental changes. |
| `add_supplier_keywords` | Adds dashboard keywords/categories without removing existing keywords. |
| `remove_supplier_keywords` | Removes dashboard keywords/categories without changing other keywords. |
| `add_supplier_certifications` | Adds certifications without removing existing certifications. |
| `remove_supplier_certifications` | Removes certifications without changing other certifications. |
| `list_supplier_addresses` | Lists supplier dashboard addresses. |
| `add_supplier_address` | Adds an address to the supplier profile. |
| `update_supplier_address` | Updates one address owned by the supplier. |
| `delete_supplier_address` | Deletes one supplier address. |
| `set_supplier_primary_address` | Marks one supplier address as primary. |
| `list_supplier_capacity` | Lists capacity/NIGP rows currently attached to the supplier profile. |
| `set_supplier_capacity` | Replaces the full supplier capacity list. Use add/remove tools for normal incremental NIGP changes. |
| `add_supplier_capacity_nigp_codes` | Adds internal NIGP capacity codes without removing existing capacity rows. |
| `remove_supplier_capacity_nigp_codes` | Removes internal NIGP capacity codes without changing other capacity rows. |
For supplier dashboard keywords, the API field is `city_service_ids`. For capacity, use internal
`nigp_code_id` values returned by `list_supplier_profile_options` with `kind='nigp_codes'`, not
NIGP class numbers like 204 or 208.
## Supplier media
| Tool | What it does |
| - | - |
| `list_supplier_catalogs` | Lists supplier dashboard catalog files. |
| `add_supplier_catalog` | Adds existing S3 catalog metadata. The connector does not upload binary files. |
| `delete_supplier_catalog` | Deletes one supplier catalog record. |
| `list_supplier_links` | Lists supplier dashboard website links. |
| `upsert_supplier_link` | Adds or updates a supplier dashboard link. |
| `delete_supplier_link` | Deletes one supplier dashboard link. |
| `list_supplier_videos` | Lists supplier dashboard videos. |
| `add_supplier_video` | Adds a supplier dashboard video entry. |
| `delete_supplier_video` | Deletes one supplier dashboard video entry. |
## Supplier references
| Tool | What it does |
| - | - |
| `list_supplier_references` | Lists all references owned by the authenticated supplier. |
| `get_supplier_reference` | Reads full details for one supplier reference. |
| `list_supplier_reference_requests` | Lists reference requests sent by the authenticated supplier. Verification tokens are not returned. |
| `send_supplier_reference_request` | Sends a supplier reference request to one email address. |
## Supplier solicitations
| Tool | What it does |
| - | - |
| `list_supplier_solicitations` | Lists solicitations available to the authenticated supplier. |
| `get_supplier_solicitation` | Reads one solicitation, including documents, requested items, and bid status. |
| `register_supplier_solicitation_intent` | Registers intent to bid on one solicitation. |
| `ask_supplier_solicitation_question` | Asks a question on one solicitation as the authenticated supplier. |
## Supplier Signals
| Tool | What it does |
| - | - |
| `list_supplier_signals` | Lists Signals opportunities matched to the supplier, with entity, contact, meeting date, estimated amount, matching contracts, video link, status, and pages. Read-only. |
## Supplier team and analytics
| Tool | What it does |
| - | - |
| `list_supplier_team_members` | Lists supplier team members with names, emails, role, and current flags. |
| `list_supplier_team_invites` | Lists pending supplier team invites. |
| `invite_supplier_team_member` | Invites a teammate when the signed-in supplier user can manage the team. |
| `remove_supplier_team_member` | Removes a teammate by email when permitted. |
| `update_supplier_team_member_role` | Changes a teammate role to admin or regular when permitted. |
| `get_supplier_analytics_summary` | Reads supplier dashboard analytics and profile completeness. |
## Admin tools
Admin tools require a CivicMarketplace admin account plus `admin:read` or `admin:write`.
| Tool family | Tools |
| - | - |
| Search records | `admin_search_suppliers`, `admin_search_agencies`, `admin_search_coops`, `admin_search_contracts` |
| Get records | `admin_get_supplier`, `admin_get_suppliers`, `admin_get_agency`, `admin_get_coop`, `admin_get_contract` |
| Create records | `admin_create_supplier`, `admin_create_agency`, `admin_create_coop`, `admin_create_contract` |
| Update records | `admin_update_supplier`, `admin_update_agency`, `admin_update_coop`, `admin_update_contract` |
| Contract status | `admin_set_contract_status` |
| Supplier relationships | `admin_add_supplier_nigp_codes`, `admin_remove_supplier_nigp_codes`, `admin_set_supplier_nigp_codes`, `admin_add_supplier_tags`, `admin_remove_supplier_tags`, `admin_set_supplier_tags`, `admin_add_supplier_categories`, `admin_remove_supplier_categories`, `admin_set_supplier_categories`, `admin_add_supplier_certifications`, `admin_remove_supplier_certifications`, `admin_set_supplier_certifications`, `admin_add_supplier_regions`, `admin_remove_supplier_regions`, `admin_set_supplier_regions` |
| Contract relationships | `admin_add_contract_suppliers`, `admin_remove_contract_suppliers`, `admin_set_contract_suppliers`, `admin_add_contract_nigp_codes`, `admin_remove_contract_nigp_codes`, `admin_set_contract_nigp_codes`, `admin_add_contract_tags`, `admin_remove_contract_tags`, `admin_set_contract_tags`, `admin_add_contract_themes`, `admin_remove_contract_themes`, `admin_set_contract_themes`, `admin_add_contract_city_services`, `admin_remove_contract_city_services`, `admin_set_contract_city_services` |
| Agency relationships | `admin_add_agency_cooperatives`, `admin_remove_agency_cooperatives`, `admin_set_agency_cooperatives` |
Some write tools create new records or send notifications. Relationship set/remove tools and quote
request archive/cancel tools can change existing state. Your AI assistant may ask for confirmation
before using these tools depending on its own MCP permission settings.
# Get Contract
Source: https://docs.civicmarketplace.com/api-reference/contracts/get-contract
GET /v1/contracts/{id}
# List Contracts
Source: https://docs.civicmarketplace.com/api-reference/contracts/list-contracts
GET /v1/contracts
# API Reference
Source: https://docs.civicmarketplace.com/api-reference/overview
Complete reference for all CivicMarketplace Partner API endpoints
The Partner API is a read-only REST API. All endpoints return JSON and require authentication via Bearer token.
## Base URL
```
https://prod-api.civicmarketplace.com
```
## Resources
Cooperative purchasing contracts with associated suppliers, lead entities, and city services.
Open and historic solicitations (RFPs) with their deadlines, requested items, and public
notices.
Vendor details including name, location, contact info, and logo.
Reference data: lead entities, cooperatives, and city service categories.
## Common patterns
All list endpoints share these behaviors:
* **Pagination**: Cursor-based. See [Pagination](/pagination).
* **Authentication**: Bearer token required. See [Authentication](/authentication).
* **Rate limiting**: 60 requests/minute per key. See [Rate Limits](/rate-limits).
* **Error format**: Consistent error envelope. See [Errors](/errors).
# Count Solicitations
Source: https://docs.civicmarketplace.com/api-reference/solicitations/count-solicitations
GET /v1/solicitations/count
Total matching the same filters as the list endpoint, minus cursor and limit.
# Get Solicitation
Source: https://docs.civicmarketplace.com/api-reference/solicitations/get-solicitation
GET /v1/solicitations/{id}
# List Solicitations
Source: https://docs.civicmarketplace.com/api-reference/solicitations/list-solicitations
GET /v1/solicitations
Open and historic solicitations (RFPs) issued by the lead entities in this partner's scope. Drafts are never returned. Results are ordered by id for stable cursor pagination — use `closing_before` / `closing_after` to narrow to a deadline window rather than relying on order.
`updated_at` tracks the solicitation record only. Adding a public notice or a document does not touch it, so `updated_since` will not surface an addendum on a solicitation you have already synced. Re-read the detail endpoint for those.
# Get Supplier
Source: https://docs.civicmarketplace.com/api-reference/suppliers/get-supplier
GET /v1/suppliers/{id}
# List Suppliers
Source: https://docs.civicmarketplace.com/api-reference/suppliers/list-suppliers
GET /v1/suppliers
# List Certifications
Source: https://docs.civicmarketplace.com/api-reference/taxonomy/list-certifications
GET /v1/certifications
Master list of certifications suppliers can hold — SBE/diversity (DBE, MBE, HUB, WOSB…) and technical (ISO 37001, AZ-104, A+…). Use the returned abbreviation or name as the `certification` filter on /v1/suppliers.
# List City Services
Source: https://docs.civicmarketplace.com/api-reference/taxonomy/list-city-services
GET /v1/city-services
# List Cooperatives
Source: https://docs.civicmarketplace.com/api-reference/taxonomy/list-coops
GET /v1/coops
# List Lead Entities
Source: https://docs.civicmarketplace.com/api-reference/taxonomy/list-lead-entities
GET /v1/lead-entities
# Authentication
Source: https://docs.civicmarketplace.com/authentication
Authenticate with the Partner API using Bearer tokens
All API requests (except `/health`) require a valid API key passed as a Bearer token in the `Authorization` header.
## API key format
```
cmp_live_aBcDeFgH.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
| Segment | Description |
| - | - |
| `cmp` | Key prefix (always `cmp`) |
| `live` or `test` | Environment (`live` for production, `test` for sandbox) |
| `aBcDeFgH` | 8-character lookup identifier |
| `.xxx...` | 44-character secret |
## Making authenticated requests
Pass your key in the `Authorization` header with the `Bearer` scheme:
```bash theme={null}
curl https://prod-api.civicmarketplace.com/v1/contracts \
-H "Authorization: Bearer cmp_live_aBcDeFgH.your_secret_here"
```
## Environments
| Environment | Key prefix | Base URL |
| - | - | - |
| Production | `cmp_live_` | `https://prod-api.civicmarketplace.com` |
| Sandbox | `cmp_test_` | `https://api.dev.civicmarketplace.com` |
**A key belongs to exactly one environment.** Each environment has its own
database, and a key only exists in the one it was issued from — so a `cmp_test_`
key returns `401` against production, and a `cmp_live_` key returns `401`
against the sandbox. There is no key that works in both.
Build against the sandbox first. Its data is non-production and safe to hammer,
and the request and response shapes are identical to production, so moving over
is a change of base URL and key, nothing else.
When you are ready for production, ask your account manager for a `cmp_live_`
key. It is issued separately; production keys cannot be generated from sandbox.
## Data scoping
Each API key is scoped to a partner account. You will only see contracts and suppliers that your partner account has been granted access to. If you need access to additional data, contact your account manager.
## Key rotation
**Rotation takes effect immediately.** The replacement is issued and the old key
is revoked in the same step, so there is no overlap window and no grace period —
the old key starts returning `401` the moment the new one is created.
Plan for that: have the deployment of the new key ready before requesting the
rotation, so the gap is as short as possible.
1. Ask your account manager to rotate the key, and agree a time
2. Receive the replacement, which is shown once and cannot be retrieved later
3. Deploy it
If you only need to retire a key you have already replaced, ask for a revoke
instead of a rotate.
## Error responses
If your key is missing, invalid, or revoked:
```json theme={null}
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key",
"request_id": "req_abc123"
}
}
```
Data outside your partner scope is **filtered out rather than refused**. A
collection returns `200` with the out-of-scope rows absent, and a single
out-of-scope record returns `404` — the same as one that does not exist, so the
API never confirms whether a record you cannot see is real.
An empty `data` array therefore means "nothing in your scope matched", which can
mean the filters excluded everything, or that your account has not been granted
the relevant contracts, co-ops or suppliers yet. If you expect results and get
none, check your scope with your account manager before debugging the query.
# Errors
Source: https://docs.civicmarketplace.com/errors
Understand error responses and how to handle them
The API uses standard HTTP status codes and returns a consistent error envelope for all error responses.
## Error format
```json theme={null}
{
"error": {
"code": "not_found",
"message": "The requested contract does not exist or is not accessible",
"request_id": "req_abc123def456"
}
}
```
| Field | Description |
| - | - |
| `code` | Machine-readable error code (see table below) |
| `message` | Human-readable description of the error |
| `request_id` | Unique identifier for this request. Include this when contacting support. |
## Error codes
| HTTP Status | Code | Description |
| - | - | - |
| `400` | `validation_failed` | Invalid query parameters or request format |
| `401` | `unauthorized` | Missing or invalid API key |
| `403` | `forbidden` | Valid key but resource is outside your partner scope |
| `404` | `not_found` | Resource does not exist or is not accessible |
| `429` | `rate_limited` | Too many requests. See [Rate Limits](/rate-limits) |
| `500` | `internal_error` | Something went wrong on our end |
## Handling errors
```javascript theme={null}
const response = await fetch(url, { headers });
if (!response.ok) {
const body = await response.json();
const { code, message, request_id } = body.error;
switch (code) {
case "rate_limited":
const retryAfter = response.headers.get("Retry-After");
// Wait and retry
break;
case "unauthorized":
// Check your API key
break;
case "not_found":
// Resource doesn't exist or isn't in your scope
break;
default:
console.error(`API error [${request_id}]: ${code} - ${message}`);
}
}
```
## Request IDs
Every response includes an `X-Request-ID` header. When reporting issues, include this ID so we can trace the exact request in our logs.
```bash theme={null}
curl -v https://prod-api.civicmarketplace.com/v1/contracts/ctr_invalid \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
# Response headers will include:
# X-Request-ID: req_abc123def456
```
# Filtering & Search
Source: https://docs.civicmarketplace.com/guides/filtering-and-search
Narrow down contracts and suppliers using filters and full-text search
The API supports filtering by related entities and full-text keyword search across contracts and suppliers.
## Text search
Use the `q` parameter to search by keyword (max 200 characters):
```bash theme={null}
# Search contracts
curl "https://prod-api.civicmarketplace.com/v1/contracts?q=office+supplies" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
# Search suppliers
curl "https://prod-api.civicmarketplace.com/v1/suppliers?q=Acme" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
```
## Filtering contracts
Contracts can be filtered by their related entities using opaque IDs:
| Parameter | Description | Example |
| - | - | - |
| `lead_entity` | Filter by lead entity | `?lead_entity=le_abc123` |
| `coop` | Filter by cooperative | `?coop=co_def456` |
| `supplier` | Filter by supplier | `?supplier=sup_ghi789` |
| `city_service` | Filter by city service category | `?city_service=cs_jkl012` |
### Getting filter IDs
Use the taxonomy endpoints to look up valid IDs:
```bash theme={null}
# List all lead entities
curl "https://prod-api.civicmarketplace.com/v1/lead-entities" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
# List all cooperatives
curl "https://prod-api.civicmarketplace.com/v1/coops" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
# List all city services
curl "https://prod-api.civicmarketplace.com/v1/city-services" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
```
## Combining filters
You can combine filters with search and date ranges:
```bash theme={null}
# Contracts from a specific coop, updated in the last week, matching "consulting"
curl "https://prod-api.civicmarketplace.com/v1/contracts?coop=co_def456&q=consulting&updated_since=2026-04-15T00:00:00Z" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
```
## Date filtering
Use `updated_since` (ISO 8601 format) to get records modified after a specific time:
```bash theme={null}
# Contracts updated after April 1, 2026
curl "https://prod-api.civicmarketplace.com/v1/contracts?updated_since=2026-04-01T00:00:00Z" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
```
Combine `updated_since` with cursor pagination for efficient incremental syncing. See the [Syncing
Data](/guides/syncing-data) guide.
# Syncing Data
Source: https://docs.civicmarketplace.com/guides/syncing-data
Keep a local copy of contracts and suppliers up to date
If you maintain a local database of CivicMarketplace data, use incremental syncing to stay up to date without re-fetching everything.
## How incremental sync works
1. **Initial sync**: Page through all records using cursor pagination
2. **Subsequent syncs**: Use `updated_since` to fetch only records that changed since your last sync
## Step 1: Initial full sync
Fetch all contracts, paginating until `next_cursor` is `null`:
```javascript theme={null}
async function initialSync(apiKey) {
const contracts = [];
let cursor = null;
do {
const url = new URL("https://prod-api.civicmarketplace.com/v1/contracts");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const page = await res.json();
contracts.push(...page.data);
cursor = page.meta.next_cursor;
} while (cursor);
// Store contracts and record the current timestamp
await saveContracts(contracts);
await saveLastSyncTime(new Date().toISOString());
}
```
## Step 2: Incremental updates
On subsequent syncs, pass your last sync timestamp as `updated_since`:
```javascript theme={null}
async function incrementalSync(apiKey) {
const lastSync = await getLastSyncTime();
const updated = [];
let cursor = null;
do {
const url = new URL("https://prod-api.civicmarketplace.com/v1/contracts");
url.searchParams.set("limit", "100");
url.searchParams.set("updated_since", lastSync);
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const page = await res.json();
updated.push(...page.data);
cursor = page.meta.next_cursor;
} while (cursor);
await upsertContracts(updated);
await saveLastSyncTime(new Date().toISOString());
}
```
## Sync schedule recommendations
| Use case | Recommended interval |
| - | - |
| Real-time dashboard | Every 5 minutes |
| Daily reporting | Once per day |
| Search index | Every 15-30 minutes |
The `updated_since` filter works with cursor pagination, so even if thousands of records changed,
you can page through them safely.
## Syncing suppliers
The same pattern works for suppliers:
```bash theme={null}
curl "https://prod-api.civicmarketplace.com/v1/suppliers?updated_since=2026-04-20T00:00:00Z&limit=100" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
```
# Introduction
Source: https://docs.civicmarketplace.com/introduction
Access cooperative contract and supplier data through the CivicMarketplace Partner API
The CivicMarketplace Partner API gives you read-only access to cooperative purchasing contracts, suppliers, and reference taxonomy data. Use it to integrate contract and supplier information into your own applications, dashboards, and workflows.
Prefer to ask questions in plain English instead of writing code? The [AI
Connector](/ai-connector/overview) brings the same data into ChatGPT, Claude, and Microsoft
Copilot — no API key required.
## What you can do
Query cooperative purchasing contracts by keyword, lead entity, coop, supplier, or city service.
Look up supplier details including contact info, location, and associated contracts.
Use cursor pagination and `updated_since` filters to keep your data in sync without full
re-fetches.
Access lead entities, cooperatives, and city service categories to filter and organize results.
## Base URL
All API requests go to:
```
https://prod-api.civicmarketplace.com
```
A sandbox is also available, with its own keys:
| Environment | Key prefix | Base URL |
| - | - | - |
| **Production** | `cmp_live_` | `https://prod-api.civicmarketplace.com` |
| **Sandbox** | `cmp_test_` | `https://api.dev.civicmarketplace.com` |
A key works against one environment only. See [Authentication](/authentication)
for how the two differ.
## Quick example
```bash theme={null}
curl https://prod-api.civicmarketplace.com/v1/contracts?q=IT+consulting&limit=5 \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
```
```json theme={null}
{
"data": [
{
"id": "ctr_abc123",
"name": "IT Consulting Services",
"summary": "Professional IT consulting and advisory services",
"lead_entity": { "id": "le_xyz", "name": "City of Austin" },
"coop": { "id": "co_456", "name": "Sourcewell" },
"suppliers": [
{
"id": "sup_789",
"name": "Acme Tech Solutions",
"location": "Austin, TX",
"email": "contracts@acmetech.com"
}
],
"city_services": [{ "id": "cs_101", "name": "Information Technology" }],
"updated_at": "2026-04-20T14:30:00Z"
}
],
"meta": {
"next_cursor": "eyJpZCI6MTIzfQ",
"limit": 5
}
}
```
Don't have an API key yet? Apply for partner access.
Already have a key? Make your first API call.
# FAQ
Source: https://docs.civicmarketplace.com/marketing/faq
Frequently asked questions about the CivicMarketplace API
The Partner API provides read-only access to cooperative purchasing contracts, suppliers, and reference taxonomy (lead entities, cooperatives, and city service categories).
Visit the [Request Access](/request-access) page to apply. We respond within 2 business days.
API access is included with your CivicMarketplace partner agreement. Contact your account manager for details on your plan.
The default rate limit is 60 requests per minute per API key. If your integration requires higher limits, contact us to discuss your needs.
The Partner API is read-only. If you have a use case that requires write access, reach out to discuss it with our team.
Yes. Use a `cmp_test_` API key with `https://uat-api.civicmarketplace.com` for development and testing.
# Support
Source: https://docs.civicmarketplace.com/marketing/support
Get help with the CivicMarketplace API
## Contact us
Reach us at [support@civicmarketplace.com](mailto:support@civicmarketplace.com) for technical questions and bug reports.
For API access, partnerships, and account questions, email [partners@civicmarketplace.com](mailto:partners@civicmarketplace.com).
## When contacting support
To help us resolve your issue quickly, please include:
* Your **partner name** or account identifier
* The **request ID** from the error response (`request_id` field or `X-Request-ID` header)
* The **endpoint** you were calling
* The **full error response** you received
* Any relevant **timestamps**
## System status
Check [status.civicmarketplace.com](https://status.civicmarketplace.com) for real-time API availability and incident updates.
# Use Cases
Source: https://docs.civicmarketplace.com/marketing/use-cases
How organizations use the CivicMarketplace API
## Procurement integration
**Placeholder** -- Marketing team: replace this section with a real customer use case about integrating contract data into procurement software.
Organizations integrate CivicMarketplace contract data directly into their procurement workflows, giving buyers instant access to cooperatively bid contracts without leaving their existing tools.
## Spend analytics
**Placeholder** -- Marketing team: replace this section with a real customer use case about building analytics dashboards with supplier and contract data.
Analytics teams use the API to pull contract and supplier data into dashboards, tracking spend across cooperatives and identifying cost-saving opportunities.
## Supplier discovery
**Placeholder** -- Marketing team: replace this section with a real customer use case about supplier search and discovery.
Agencies use the API's search and filtering capabilities to discover qualified suppliers across multiple cooperatives, streamlining the vendor selection process.
# Pagination
Source: https://docs.civicmarketplace.com/pagination
Navigate large result sets with cursor-based pagination
The API uses cursor-based pagination for all list endpoints. This approach is safe for incremental syncing and handles data changes between pages gracefully.
## How it works
Every list response includes a `meta` object:
```json theme={null}
{
"data": [...],
"meta": {
"next_cursor": "eyJpZCI6NDUsInVwZGF0ZWRfYXQiOiIyMDI2LTA0LTE1VDA5OjAwOjAwWiJ9",
"limit": 25
}
}
```
* `next_cursor` is an opaque string. Pass it as the `cursor` query parameter to get the next page.
* When `next_cursor` is `null`, you've reached the last page.
## Paging through results
```bash theme={null}
# First page
curl "https://prod-api.civicmarketplace.com/v1/contracts?limit=25" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
# Next page (use next_cursor from previous response)
curl "https://prod-api.civicmarketplace.com/v1/contracts?limit=25&cursor=eyJpZCI6NDV9" \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
```
## Page size
Control the number of results per page with the `limit` parameter:
| Parameter | Default | Min | Max |
| - | - | - | - |
| `limit` | 25 | 1 | 100 |
## Full pagination example
```javascript theme={null}
async function fetchAllContracts(apiKey) {
const contracts = [];
let cursor = null;
do {
const url = new URL("https://prod-api.civicmarketplace.com/v1/contracts");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const response = await fetch(url, {
headers: { Authorization: `Bearer ${apiKey}` },
});
const page = await response.json();
contracts.push(...page.data);
cursor = page.meta.next_cursor;
} while (cursor);
return contracts;
}
```
Combine pagination with `updated_since` to efficiently sync only changed records. See the [Syncing
Data](/guides/syncing-data) guide.
# Quickstart
Source: https://docs.civicmarketplace.com/quickstart
Make your first API call in under 5 minutes
## 1. Get your API key
[Request access](/request-access) if you don't have a key yet, or contact your CivicMarketplace account manager.
You'll receive a key in this format:
```
cmp_live_aBcDeFgH.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
Keep your API key secret. Do not commit it to version control or expose it in client-side code.
## 2. Make your first request
Test your key by listing contracts:
```bash cURL theme={null}
curl https://prod-api.civicmarketplace.com/v1/contracts?limit=3 \
-H "Authorization: Bearer cmp_live_YOUR_KEY"
```
```javascript Node.js theme={null}
const response = await fetch("https://prod-api.civicmarketplace.com/v1/contracts?limit=3", {
headers: {
Authorization: "Bearer cmp_live_YOUR_KEY",
},
});
const data = await response.json();
console.log(data);
```
```python Python theme={null}
import requests
response = requests.get(
"https://prod-api.civicmarketplace.com/v1/contracts",
params={"limit": 3},
headers={"Authorization": "Bearer cmp_live_YOUR_KEY"},
)
print(response.json())
```
## 3. Explore the data
A successful response looks like this:
```json theme={null}
{
"data": [
{
"id": "ctr_abc123",
"name": "Office Supplies Contract",
"summary": "Competitively bid office supplies agreement",
"lead_entity": { "id": "le_001", "name": "City of Houston" },
"coop": { "id": "co_002", "name": "TIPS" },
"suppliers": [{ "id": "sup_003", "name": "Office Depot", "location": "Boca Raton, FL" }],
"city_services": [{ "id": "cs_004", "name": "General Government" }],
"updated_at": "2026-04-15T09:00:00Z"
}
],
"meta": {
"next_cursor": "eyJpZCI6NDV9",
"limit": 3
}
}
```
## 4. Next steps
Learn about API key scoping and environments.
Page through large result sets with cursors.
Narrow results by keyword, entity, and date.
Keep a local copy of contracts up to date.
# Rate Limits
Source: https://docs.civicmarketplace.com/rate-limits
Understand and work within API rate limits
The API enforces rate limits per API key to ensure fair usage and service reliability.
## Default limits
| Limit | Value |
| - | - |
| Requests per minute | 60 |
| Window | 60 seconds (sliding) |
## Rate limit headers
Every response includes headers showing your current usage:
| Header | Description |
| - | - |
| `X-RateLimit-Limit` | Maximum requests allowed per window |
| `X-RateLimit-Remaining` | Requests remaining in current window |
| `X-RateLimit-Reset` | Unix timestamp when the window resets |
## When you hit the limit
If you exceed the rate limit, the API returns a `429` response with a `Retry-After` header:
```json theme={null}
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Retry after 12 seconds.",
"request_id": "req_abc123"
}
}
```
```
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1714060800
```
## Best practices
When you receive a 429, wait for the `Retry-After` duration before retrying. If retries continue
to fail, increase the wait time exponentially.
If you're reading the same data repeatedly, cache it locally and use `updated_since` for
incremental updates instead of re-fetching everything.
Set `limit=100` to fetch more results per request, reducing the total number of API calls
needed.
## Need higher limits?
If your integration requires a higher rate limit, contact [partners@civicmarketplace.com](mailto:partners@civicmarketplace.com) with details about your use case.
# Request API Access
Source: https://docs.civicmarketplace.com/request-access
Apply for access to the CivicMarketplace Partner API
The CivicMarketplace Partner API is available to organizations that want to integrate cooperative purchasing data into their products and workflows.
## What you get
Search and retrieve cooperative purchasing contracts across multiple cooperatives and lead
entities.
Access supplier details including contact information, locations, and contract associations.
Filter by lead entity, cooperative, city service category, and more.
Test your integration against sandbox data before going live.
## How to apply
Send us the following information and we will get back to you within 2 business days.
Your company name, website, and a brief description of what you do.
How do you plan to use CivicMarketplace data? What problem are you solving for your users?
Expected request volume, the environments you need (production, sandbox, or both), and your
preferred technical contact.
Email **[partners@civicmarketplace.com](mailto:partners@civicmarketplace.com)** to get started. We will respond within 2 business days.
## Already have access?
If you already have an API key, head to the [quickstart guide](/quickstart) to make your first request.