Authentication
Generate a key on your account page. Keys look like rfk_ followed by 40 hexadecimal characters. Send it in the Authorization header on every request. The key is shown once; we keep only its SHA-256 hash, so a lost key is rotated, not recovered.
curl -H 'Authorization: Bearer rfk_YOUR_KEY' https://rfpfinder.net/api/v1/me
Limits, errors and headers
| Status | Code | When |
|---|---|---|
| 400 | bad_request | A parameter is malformed, for example state=Texas or since=yesterday. The message says which. |
| 401 | unauthorized | No key, a malformed key or a revoked key. |
| 403 | plan_required | The key belongs to an account that is no longer on Team. |
| 404 | not_found | No notice, vendor or endpoint at that address. |
| 429 | rate_limited | More than 1,000 requests this hour. Wait for Retry-After seconds. |
{
"error": {
"code": "bad_request",
"message": "state must be a two-letter US state or territory code"
}
}Every response is Content-Type: application/json; charset=utf-8 and Cache-Control: private, no-store, with X-RateLimit-Limit and X-RateLimit-Remaining. Lists return { data, page, per, total, next }; total counts up to 10,000 and adds total_capped: true past that. Dates are UTC ISO 8601. Values are US dollars as stated by the agency, often missing.
Endpoints
GET /api/v1/me
Your plan, seats, saved profile and how many requests are left this hour.
Examplecurl -H 'Authorization: Bearer rfk_YOUR_KEY' https://rfpfinder.net/api/v1/meResponse shape, values elided
{
"data": {
"email": "you@company.com",
"plan": "team",
"seats": 5,
"key_created": "…",
"profile": {
"categories": ["janitorial"],
"states": ["TX"],
"naics": ["561720"],
"set_asides": ["small-business"],
"keywords": [],
"exclude": ["snow removal"]
},
"rate_limit": {
"limit": 1000,
"remaining": "…",
"reset_in_seconds": "…"
}
}
}GET /api/v1/rfps
Open notices, soonest deadline first. Uses the same open definition as the site: open, not a duplicate, a solicitation, combined synopsis or presolicitation, and either a future deadline or no stated deadline and posted in the last 90 days.
| Parameter | Meaning |
|---|---|
| category | category slug (see /api/v1/categories) |
| state | two-letter code, place of performance |
| naics | 2 to 6 digits, prefix match |
| psc | 1 to 4 characters, prefix match |
| set_aside | small-business, 8a, wosb, sdvosb, hubzone, vosb … |
| agency_type | federal, state, county, city, school-district, university, other |
| q | full-text search over title, summary, agency, description and document text (the same index as /search/) |
| since | ISO date or date-time; notices first seen after it |
| due_before | ISO date or date-time; deadline before it |
| min_value, max_value | whole dollars, on the stated maximum value |
| sort | due (default) or new (first seen, newest first) |
| page, per | per is 1 to 100, default 50; page × per stays within 10,000 rows |
curl -H 'Authorization: Bearer rfk_YOUR_KEY' 'https://rfpfinder.net/api/v1/rfps?category=janitorial&state=TX&per=2'Response, live data, trimmed to the first rows
{
"data": [
{
"id": "r_1d594c5b925d6f7f",
"slug": "hearne-janitorial-services-1d594c5b",
"url": "https://rfpfinder.net/rfp/hearne-janitorial-services-1d594c5b/",
"title": "Hearne Janitorial Services",
"agency": "Department Of Public Safety",
"agency_type": "state",
"state": "TX",
"city": null,
"kind": "solicitation",
"notice_type": null,
"solicitation_number": "405-26R0024627",
"status": "open",
"posted_at": "2026-09-21T05:00:00Z",
"due_at": "2026-10-13T22:00:00Z",
"first_seen": "2026-10-08T16:26:50Z",
"est_value_min": 40334,
"est_value_max": 40334,
"naics": [],
"psc": "91039",
"set_asides": [],
"categories": ["janitorial"],
"summary": "DPS is seeking bids for Janitorial Services at the DPS Driver's License Office located at Hearne, TX. Bids will be evaluated based on the lowest price.",
"source_url": "https://www.txsmartbuy.gov/esbd/405-26R0024627",
"updated_at": "2026-10-08T18:19:04Z"
}
],
"page": 1,
"per": 2,
"total": 10,
"next": "https://rfpfinder.net/api/v1/rfps?category=janitorial&state=TX&per=2&page=2"
}GET /api/v1/rfps/matching
Your saved profile applied: categories and states, set-asides, value range, buyer types, keywords, NAICS codes and excluded words, the same filters your alert emails use. Defaults to notices first seen in the last 7 days (override with since); every query filter above also works here to narrow further. Each row carries a fit score and the reasons.
Examplecurl -H 'Authorization: Bearer rfk_YOUR_KEY' 'https://rfpfinder.net/api/v1/rfps/matching?sort=new'Response shape, values elided
{
"data": [
{
"slug": "…",
"title": "…",
"due_at": "…",
"fit": {
"score": 5,
"why": ["NAICS 561720", "TX"]
}
}
],
"page": 1,
"per": 50,
"total": "…",
"next": null,
"since": "…",
"profile": {
"categories": ["janitorial"],
"states": ["TX"]
}
}GET /api/v1/rfps/{slug}
One notice by its slug (the last part of its RFPFinder URL), with the description, the documents we hold (links to our /docs/ copies) and the change history: deadline moves, amendments, Q&A postings.
Examplecurl -H 'Authorization: Bearer rfk_YOUR_KEY' https://rfpfinder.net/api/v1/rfps/SLUGResponse shape, values elided
{
"data": {
"slug": "…",
"title": "…",
"due_at": "…",
"description": "…",
"documents": [
{
"name": "Solicitation.pdf",
"size": "…",
"pages": "…",
"mime": "application/pdf",
"url": "https://rfpfinder.net/docs/docs/r_…/Solicitation.pdf",
"source_url": "https://…"
}
],
"changes": [
{
"id": "…",
"detected_at": "…",
"kind": "deadline_moved",
"old_value": "…",
"new_value": "…",
"note": null
}
]
}
}GET /api/v1/awards
Federal (USAspending) and state and local awards, newest first, or soonest-ending first with expiring_before. Give at least one of vendor, naics, psc, state or expiring_before; agency, level and since narrow those.
| Parameter | Meaning |
|---|---|
| vendor | vendor slug, or part of a company name |
| agency | part of the agency or sub-agency name |
| naics, psc | prefix match |
| state | two-letter code (state and local awards carry a state) |
| level | federal, state or local |
| since | awarded on or after this date |
| expiring_before | period of performance ends between today and this date |
| page, per | per is 1 to 100, default 50 |
curl -H 'Authorization: Bearer rfk_YOUR_KEY' 'https://rfpfinder.net/api/v1/awards?naics=561720&expiring_before=2027-06-30'Response shape, values elided
{
"data": [
{
"award_id": "…",
"level": "federal",
"agency": "…",
"awardee": "…",
"vendor_slug": "…",
"amount": "…",
"awarded_at": "…",
"ends_at": "…",
"naics": "561720",
"psc": "S201"
}
],
"page": 1,
"per": 50,
"total": "…",
"next": "…"
}GET /api/v1/vendors/{slug}
One contractor: award counts and totals, top agencies, codes and states, its 25 most recent awards and the ones ending in the next 12 months.
Examplecurl -H 'Authorization: Bearer rfk_YOUR_KEY' https://rfpfinder.net/api/v1/vendors/SLUGResponse shape, values elided
{
"data": {
"slug": "…",
"name": "…",
"awards_n": "…",
"total_amount": "…",
"top_agencies": ["…"],
"recent_awards": ["…"],
"expiring_awards": ["…"]
}
}GET /api/v1/categories and /api/v1/states
Open counts per category (with the beta flag) and per state, plus counts per buyer type.
Examplecurl -H 'Authorization: Bearer rfk_YOUR_KEY' https://rfpfinder.net/api/v1/categoriesResponse, live data, trimmed to the first rows
{
"data": [
{
"slug": "it",
"name": "IT & Software",
"description": "Software, cloud, data, cybersecurity and IT services solicitations.",
"open": 327,
"beta": true
},
{
"slug": "marketing",
"name": "Marketing",
"description": "Marketing, advertising, PR, branding and communications RFPs.",
"open": 56,
"beta": true
}
]
}RSS feed
Your personal feed lists open notices first seen in the last 14 days that match your saved profile, newest first, up to 100 items. Each item title reads "title · due date · agency"; the description carries the summary, deadline, value, set-asides and a link to the notice. Feed readers cannot send headers, so the key goes in the URL: treat the feed URL like a password. Add category and state to replace your profile with those two filters.
https://rfpfinder.net/feed.xml?key=rfk_YOUR_KEY https://rfpfinder.net/feed.xml?key=rfk_YOUR_KEY&category=janitorial&state=TX
Changelog
- 2026-10-08
- Version 1: /me, /rfps, /rfps/matching, /rfps/{slug}, /awards, /vendors/{slug}, /categories, /states and the RSS feed.
Questions
Which plan includes the API?
The Team plan. Each Team account has one key at a time; generating a new key replaces the old one at once.
How do I get a key?
Sign in on the account page, open the API and RSS panel and press Generate key. The key is shown once; we store only a SHA-256 hash of it, so we cannot show it again. If you lose it, rotate it.
What is the rate limit?
1,000 requests per hour per key, counted per UTC hour. A request over the limit gets HTTP 429 with a Retry-After header. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining.
Can I call the API from a browser?
Yes. GET responses allow any origin, because the key travels in the Authorization header rather than a cookie. Do not put your key in public front-end code: anyone who reads it can use your quota.
How fresh is the data?
The same as the site: SAM.gov and state and local portals are fetched several times a day, and award data is refreshed nightly. Responses are never cached.
Can I republish the data?
You can use it inside your company and in your own tools. Reselling the feed or republishing it as a competing listing service is not allowed under the terms of use.