Skip to content

This is the staging environment's documentation. It is a draft and may change at any time.

Search notices

POST
/search
curl --request POST \
--url https://api-staging.fedwright.com/v1/search \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "facets": [ "setAsideProgram", "department" ], "filters": { "naics": [ "3364" ], "noticeTypes": [ "Solicitation", "Combined Synopsis/Solicitation" ], "phases": [ "open" ], "psc": [ "15" ] }, "groupByThread": true, "includeHistory": false, "limit": 20, "q": "step assy", "semanticRatio": 0.3, "sort": [ "responseDeadline" ] }'

Full-text search with structured filters, facets, and sorting. Saved searches store the same SearchRequest. By default only opportunity notice types that aren’t archived are searched; includeHistory adds award notices, justifications, and archived notices. At most 5,000 results can be paged through; narrow the filters to reach others. A facet combination that needs more than 16 queries returns 422 validation-failed at facets. A facet that cannot be counted in full within a bounded number of extra queries is named in incompleteFacets. A cursor can become invalid when search data is refreshed: it then returns 400 invalid-cursor, and pagination restarts from the first page. semanticRatio asks for hybrid search, which mixes ranking by meaning into ranking by words; it is best effort, and the response’s semantic says what ran. A search that ranks by meaning is premium: it uses one of the organization’s premium units for the day. When the units can’t cover it, or the plan has none, the search still succeeds, ranked by words alone, and semantic.reason is premiumQuota.

Media typeapplication/json

A SearchQuery, with paging. At most 5,000 results can be paged through; the last page has a null nextCursor. Concurrent notice changes can shift or duplicate hits between pages. A cursor can become invalid when search data is refreshed: it then returns 400 invalid-cursor, and pagination restarts from the first page.

object
facets

Facets to count over the matching notices. A combination of requested hierarchy levels and necessary splits that needs more than 16 queries returns 422 validation-failed at facets.

Array<string>
unique items
Allowed values: noticeType phase naics psc setAsideProgram department subTier placeState placeCountry label condition
filters

Every filter is optional. Values within one filter are alternatives (OR); different filters must all hold (AND). Free-text array items cannot contain backslashes or control characters.

object
acceptingResponses

When true, include only forecast, presolicitation, and solicitation notices whose current response deadline is after the search time or missing. False or absent applies no filter. Unlike the open phase, this includes Sources Sought and Special Notices in forecast and notices in presolicitation. A date-only deadline ends at midnight after its date in US Eastern time.

boolean
awardAmountMax

Include only notices whose award amount is at most this amount, as a decimal string.

string
/^[0-9]+(\.[0-9]+)?$/
awardAmountMin

Include only notices whose award amount is at least this amount, as a decimal string.

string
/^[0-9]+(\.[0-9]+)?$/
conditions

Enrichment conditions.

Array<string>
<= 100 items
deadlineFrom

Include only notices whose response deadline is at or after this time.

string format: date-time
deadlineTo

Include only notices whose response deadline is at or before this time.

string format: date-time
departments

Department keys.

Array<string>
<= 100 items
firstSeenFrom

Include only notices Fedwright first saw at or after this time. Using this filter leaves out historical notices.

string format: date-time
labels

Enrichment labels.

Array<string>
<= 100 items
naics

NAICS codes at any level, including range sectors such as 31-33. Older-edition codes match their current equivalents.

Array<string>
<= 100 items
noticeTypes

Include only notices of these types.

Array<string>
<= 100 items
Allowed values: Sources Sought Special Notice Presolicitation Consolidate/(Substantially) Bundle Solicitation Combined Synopsis/Solicitation Sale of Surplus Property Modification/Amendment/Cancel Award Notice Justification Justification and Approval (J&A)
phases

Phase is the notice’s stage: Sources Sought and Special Notices are forecast; open and closed apply only to solicitations and use the deadline at the time of the search. Use acceptingResponses to find notices that can still receive a response. archived requires includeHistory: true.

Array<string>
<= 100 items
Allowed values: forecast presolicitation open closed awarded archived
placeCountries

Include only notices whose place of performance is in one of these countries.

Array<string>
<= 100 items
placeStates

Include only notices whose place of performance is in one of these states or territories, by USPS code.

Array<string>
<= 100 items
postedFrom

Include only notices SAM.gov posted at or after this time.

string format: date-time
postedTo

Include only notices SAM.gov posted at or before this time.

string format: date-time
psc

PSC codes at any level, for example 61, 6145, R, R4, or R499.

Array<string>
<= 100 items
setAsideCodes

Include only notices with one of these SAM.gov set-aside codes.

Array<string>
<= 100 items
setAsidePrograms

Include only notices whose set-aside belongs to one of these programs.

Array<string>
<= 100 items
Allowed values: 8a edwosb hubzone indian_enterprise local_area sdvosb small_business vosb wosb
soleSource

When true, include only sole-source notices. When false, include only notices that are not sole-source.

boolean
subTiers

Include only notices from these sub-tier agencies, by the name SAM.gov gives.

Array<string>
<= 100 items
threadId

Opaque thread identifier; use the ID the API returns.

string
/^(N:[0-9a-f]{32}|[A-Z0-9]+:[A-Z0-9]+)$/
groupByThread

Return one result per thread, its best-matching notice.

boolean
includeHistory

Also search award notices, justifications, and archived notices.

boolean
q

Full-text query. Empty or missing matches every notice the filters allow. Only the first 10 words of a query are used.

string
<= 500 characters
sort

How to order the results, by up to three fields, applied in order. Without it, results are ordered by relevance.

Array<string>
<= 3 items
Allowed values: postedAt -postedAt firstSeenAt -firstSeenAt responseDeadline -responseDeadline awardAmount -awardAmount
cursor

nextCursor from the previous page. Send the same query with it. It expires after 24 hours and returns 400 invalid-cursor when search data is refreshed or when used with another query.

string
<= 2048 characters
limit

The number of results per page, from 1 to 200.

integer
default: 50 >= 1 <= 200
semanticRatio

How much ranking by meaning (semantic search) to mix into ranking by words: 0 is words only, 1 is meaning only. Without it, Fedwright chooses by the query’s shape: descriptive text gets the environment’s default (0.6 unless stated otherwise), and notice IDs, solicitation numbers, words with digits such as NAICS codes, quoted phrases, and single words get 0. At 0.55 or less, a query whose words many notices hold usually ranks by words alone. It is a preference, not a guarantee: when semantic ranking can’t run, the results come from ranking by words alone, and the response’s semantic says what ran and why. Filters, exact matches, counts, facets, and paging work the same either way. Semantic ranking covers only the notices indexed for it; others rank by their words alone.

number
<= 1

A page of results, with facet counts.

Media typeapplication/json

A page of search results, with the facet counts and how semantic ranking was used.

object
nextCursor
required

Cursor for the next page, or null on the last page.

null | string
estimatedTotalHits
required

Number of matching notices, including when groupByThread makes items represent threads. When semantic.applied is true, ranking by meaning orders the hits, but this still counts the notices that match by words: ranking by meaning ranks every notice the filters allow, so its own total would mean nothing.

integer
exactMatches
required

Up to five exact notice-ID or solicitation-number matches on the first page only. Empty on later pages. These hits are separate from items and do not affect page slots, estimatedTotalHits, facet counts, or nextCursor.

Array<object>
<= 5 items

One search result: a notice, with the caller’s match and the fragments that matched.

object
highlights
required

Matching fragments, HTML-escaped, with matches wrapped in <mark>. Null when the field didn’t match.

object
description
required

Fragments of the description that matched. Null when the description did not match.

null | string
title
required

The title with the matching words marked. Null when the title did not match.

null | string
match

The caller organization’s match details.

object
followLevel

How the caller’s organization follows the thread, or null if it does not follow it.

null | string
Allowed values: watching pursuing
grade
required

The score band, from A (best) to D.

string
Allowed values: A B C D
score
required

The match score as a whole number from 0 to 100.

integer
<= 100
state
One of:

A user’s own state for a match.

string
Allowed values: new seen starred dismissed
notice
required

The fields of a notice that lists and search results show.

object
active
required

True while the notice is current, meaning it is in SAM.gov’s published data now. False when it is not current, such as a notice from the historical archive or one that is no longer published.

boolean
agency
required

The department, sub-tier, and office that issued the notice.

object
department
required

The department, or null when SAM.gov gave none.

null | string
office
required

The contracting office, or null when SAM.gov gave none.

null | string
subTier
required

The sub-tier agency, or null when SAM.gov gave none.

null | string
enrichmentSummary
required

The enrichment’s summary, once the notice is enriched.

null | string
firstSeenAt
required

When Fedwright first saw the notice.

string format: date-time
id
required

SAM.gov NoticeId.

string
/^[0-9a-f]{32}$/
naicsCode
required

The notice’s NAICS code, or null when SAM.gov gave none.

null | string
placeOfPerformance
required
One of:
object
city
required

The city, or null when the notice gives none.

null | string
country
required

The country, or null when the notice gives none.

null | string
state
required

The USPS state or territory code, or null when the notice gives none.

null | string
postedAt
required

When SAM.gov posted the notice.

string format: date-time
pscCode
required

The notice’s product or service code, or null when SAM.gov gave none.

null | string
responseDeadline
required
One of:

at when the deadline has a time; date when SAM.gov gave only a date, which counts as the end of that day in US Eastern time.

object
at
required

The deadline as a point in time, or null when SAM.gov gave a date without a time.

null | string format: date-time
date
required

The deadline’s date, or null when SAM.gov gave a time as well.

null | string format: date
hasTime
required

True when SAM.gov gave a time as well as a date.

boolean
raw
required

The deadline exactly as SAM.gov gave it.

string
tzAssumed
required

True when SAM.gov gave a time without an offset, read as US Eastern.

boolean
setAside
required

The notice’s set-aside.

object
code
required

The SAM.gov set-aside code, or null when none is set.

null | string
label
required

The set-aside’s name, or null when none is set.

null | string
programs
required

The set-aside programs the code belongs to. Empty when none is set.

Array<string>
Allowed values: 8a edwosb hubzone indian_enterprise local_area sdvosb small_business vosb wosb
soleSource
required

True when the set-aside is a sole-source code.

boolean
state
required

set when the notice has a set-aside code, none_stated when SAM.gov said NONE, and missing when the field was empty.

string
Allowed values: set none_stated missing
solicitationNumber
required
One of:
object
key
required

The solicitation number in uppercase, with letters and digits only. Use it to compare numbers.

string
raw
required

The solicitation number exactly as SAM.gov gave it.

string
threadId
required

Opaque thread identifier; use the ID the API returns.

string
/^(N:[0-9a-f]{32}|[A-Z0-9]+:[A-Z0-9]+)$/
title
required

The notice’s title.

string
type
required

SAM.gov notice type, using its published label.

string
Allowed values: Sources Sought Special Notice Presolicitation Consolidate/(Substantially) Bundle Solicitation Combined Synopsis/Solicitation Sale of Surplus Property Modification/Amendment/Cancel Award Notice Justification Justification and Approval (J&A)
version
required

The notice’s version number: 1 when first seen, plus 1 for each change SAM.gov made to the notice.

integer
>= 1
threadNoticeCount
required

With groupByThread, how many notices the thread has. Otherwise null.

null | integer
>= 1
facets
required

For each requested facet, the count of matching notices for each value, including when groupByThread makes items represent threads. Counts use the same query and filters as items. A facet with no matches is an empty object. naics holds the sector level (range sectors such as 31-33 included) and the level below each selected filters.naics value, so a client can drill down to a six-digit code. psc holds the kind (P, S, R) and the level below each selected filters.psc value, keyed by hierarchy level (P:61, S:R4). phase holds open, closed, forecast, presolicitation, awarded, and archived, decided at the time of the request. setAsideProgram counts by normalized program, so SDVOSBC and SDVOSBS both count as sdvosb. Values are ordered by count, then key. When semantic.applied is true, facets count the notices that match by words, as estimatedTotalHits does.

object
key
additional properties
object
key
additional properties
integer
incompleteFacets
required

The requested facets whose counts may be missing values. Every facet is complete unless it is listed here: the server splits any facet that has 200 or more values into further queries until all of its values are counted, and lists the facet only when a bounded number of follow-up queries could not finish. The values a listed facet does return carry their full counts, but others may be absent. Narrow the filters to complete it.

Array<string>
unique items
Allowed values: noticeType phase naics psc setAsideProgram department subTier placeState placeCountry label condition
items
required

The results on this page, best match first unless a sort was requested.

Array<object>

One search result: a notice, with the caller’s match and the fragments that matched.

object
highlights
required

Matching fragments, HTML-escaped, with matches wrapped in <mark>. Null when the field didn’t match.

object
description
required

Fragments of the description that matched. Null when the description did not match.

null | string
title
required

The title with the matching words marked. Null when the title did not match.

null | string
match

The caller organization’s match details.

object
followLevel

How the caller’s organization follows the thread, or null if it does not follow it.

null | string
Allowed values: watching pursuing
grade
required

The score band, from A (best) to D.

string
Allowed values: A B C D
score
required

The match score as a whole number from 0 to 100.

integer
<= 100
state
One of:

A user’s own state for a match.

string
Allowed values: new seen starred dismissed
notice
required

The fields of a notice that lists and search results show.

object
active
required

True while the notice is current, meaning it is in SAM.gov’s published data now. False when it is not current, such as a notice from the historical archive or one that is no longer published.

boolean
agency
required

The department, sub-tier, and office that issued the notice.

object
department
required

The department, or null when SAM.gov gave none.

null | string
office
required

The contracting office, or null when SAM.gov gave none.

null | string
subTier
required

The sub-tier agency, or null when SAM.gov gave none.

null | string
enrichmentSummary
required

The enrichment’s summary, once the notice is enriched.

null | string
firstSeenAt
required

When Fedwright first saw the notice.

string format: date-time
id
required

SAM.gov NoticeId.

string
/^[0-9a-f]{32}$/
naicsCode
required

The notice’s NAICS code, or null when SAM.gov gave none.

null | string
placeOfPerformance
required
One of:
object
city
required

The city, or null when the notice gives none.

null | string
country
required

The country, or null when the notice gives none.

null | string
state
required

The USPS state or territory code, or null when the notice gives none.

null | string
postedAt
required

When SAM.gov posted the notice.

string format: date-time
pscCode
required

The notice’s product or service code, or null when SAM.gov gave none.

null | string
responseDeadline
required
One of:

at when the deadline has a time; date when SAM.gov gave only a date, which counts as the end of that day in US Eastern time.

object
at
required

The deadline as a point in time, or null when SAM.gov gave a date without a time.

null | string format: date-time
date
required

The deadline’s date, or null when SAM.gov gave a time as well.

null | string format: date
hasTime
required

True when SAM.gov gave a time as well as a date.

boolean
raw
required

The deadline exactly as SAM.gov gave it.

string
tzAssumed
required

True when SAM.gov gave a time without an offset, read as US Eastern.

boolean
setAside
required

The notice’s set-aside.

object
code
required

The SAM.gov set-aside code, or null when none is set.

null | string
label
required

The set-aside’s name, or null when none is set.

null | string
programs
required

The set-aside programs the code belongs to. Empty when none is set.

Array<string>
Allowed values: 8a edwosb hubzone indian_enterprise local_area sdvosb small_business vosb wosb
soleSource
required

True when the set-aside is a sole-source code.

boolean
state
required

set when the notice has a set-aside code, none_stated when SAM.gov said NONE, and missing when the field was empty.

string
Allowed values: set none_stated missing
solicitationNumber
required
One of:
object
key
required

The solicitation number in uppercase, with letters and digits only. Use it to compare numbers.

string
raw
required

The solicitation number exactly as SAM.gov gave it.

string
threadId
required

Opaque thread identifier; use the ID the API returns.

string
/^(N:[0-9a-f]{32}|[A-Z0-9]+:[A-Z0-9]+)$/
title
required

The notice’s title.

string
type
required

SAM.gov notice type, using its published label.

string
Allowed values: Sources Sought Special Notice Presolicitation Consolidate/(Substantially) Bundle Solicitation Combined Synopsis/Solicitation Sale of Surplus Property Modification/Amendment/Cancel Award Notice Justification Justification and Approval (J&A)
version
required

The notice’s version number: 1 when first seen, plus 1 for each change SAM.gov made to the notice.

integer
>= 1
threadNoticeCount
required

With groupByThread, how many notices the thread has. Otherwise null.

null | integer
>= 1
semantic
required

What semantic search did for a request. Semantic ranking is best effort: when it can’t run, results come from ranking by words alone, and reason says why. It covers only the notices indexed for it. When applied, model is an opaque version of the ranking, ratio is above 0, and reason is null; otherwise model is null, ratio is 0, and reason says why.

object
applied
required

Whether the results were ranked by meaning as well as by words (a hybrid query).

boolean
model
required

When applied, an opaque version of the semantic ranking used for these results; otherwise null. Compare it, don’t parse it. It changes when the ranking changes.

null | string
ratio
required

The semantic ratio that ran, 0 when not applied.

number
<= 1
reason
required

Null when applied. Otherwise why not:

  • capped: the caller’s or Fedwright’s limit for semantic queries is used up for now.
  • disabled: semantic search is off in this environment.
  • embeddingTimeout: the query couldn’t be prepared in time.
  • embeddingUnavailable: the AI provider that prepares queries is unavailable.
  • emptyQuery: there is no text to rank by meaning.
  • modelMismatch: semantic ranking was unavailable for this query, so it ran by words.
  • notRequested: the ratio is 0.
  • premiumQuota: the organization’s premium units for the day can’t cover a semantic search, or its plan has none, so the query ran by words. It is not an error.
  • semanticSearchUnavailable: the hybrid query failed, so the query ran again by words.
null | string
Allowed values: capped disabled embeddingTimeout embeddingUnavailable emptyQuery modelMismatch notRequested premiumQuota semanticSearchUnavailable

Examples

Exampledefault

A search response

{
"estimatedTotalHits": 1,
"exactMatches": [],
"facets": {
"department": {
"DEPTOFDEFENSE": 1
},
"setAsideProgram": {}
},
"incompleteFacets": [],
"items": [
{
"highlights": {
"description": null,
"title": "15--<mark>STEP</mark> <mark>ASSY</mark>"
},
"notice": {
"active": true,
"agency": {
"department": "DEPT OF DEFENSE",
"office": "NAVSUP WEAPON SYSTEMS SUPPORT",
"subTier": "DEPT OF THE NAVY"
},
"enrichmentSummary": null,
"firstSeenAt": "2026-10-03T03:41:12Z",
"id": "e6a41be9630d4261b6f3131923fdc4ce",
"naicsCode": "336413",
"placeOfPerformance": null,
"postedAt": "2026-10-02T10:25:59Z",
"pscCode": "1560",
"responseDeadline": {
"at": "2026-11-02T20:30:00Z",
"date": null,
"hasTime": true,
"raw": "2026-11-02T16:30:00-04:00",
"tzAssumed": false
},
"setAside": {
"code": null,
"label": null,
"programs": [],
"soleSource": false,
"state": "missing"
},
"solicitationNumber": {
"key": "N0038326QFC09",
"raw": "N0038326QFC09"
},
"threadId": "DEPTOFDEFENSE:N0038326QFC09",
"title": "15--STEP ASSY",
"type": "Solicitation",
"version": 1
},
"threadNoticeCount": 2
}
],
"nextCursor": null,
"semantic": {
"applied": true,
"model": "model-version-1",
"ratio": 0.3,
"reason": null
}
}

The request is malformed, or its schema refuses it: an unknown property, a value of the wrong type or outside its bounds, a limit above 200, or a sort outside the operation’s allow-list (Problem type bad-request). errors names each field by its path, such as nested.note, or $ for the body itself. The request is refused before anything is read or written. A cursor that was altered, has expired, or was issued for other filters, another sort, organization, or user returns Problem type invalid-cursor.

Media typeapplication/problem+json

RFC 9457 Problem Details.

object
detail

An explanation specific to this occurrence of the problem. It is absent for server errors.

string
errors

Validation errors, by field path.

object
key
additional properties
Array<string>
instance

A URI reference that identifies this occurrence of the problem, when the API provides one.

string
limit

On rate-limited, the quota that is used up, such as org-day. On premium-quota-exceeded, org-premium-day. A 429 with an empty body does not name it.

string
resetsAt

On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.

string format: date-time
status
required

The HTTP status code of the response, from 400 to 599.

integer
>= 400 <= 599
title
required

A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.

string
traceId
required

W3C trace ID of the failed request.

string
type
required

https://fedwright.com/problems/{code}, the same in every environment.

string format: uri

Example generated

{
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"instance": "example",
"limit": "example",
"resetsAt": "2026-04-15T12:00:00Z",
"status": 1,
"title": "example",
"traceId": "example",
"type": "https://example.com"
}

The access token is missing, expired, or invalid.

Media typeapplication/problem+json

RFC 9457 Problem Details.

object
detail

An explanation specific to this occurrence of the problem. It is absent for server errors.

string
errors

Validation errors, by field path.

object
key
additional properties
Array<string>
instance

A URI reference that identifies this occurrence of the problem, when the API provides one.

string
limit

On rate-limited, the quota that is used up, such as org-day. On premium-quota-exceeded, org-premium-day. A 429 with an empty body does not name it.

string
resetsAt

On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.

string format: date-time
status
required

The HTTP status code of the response, from 400 to 599.

integer
>= 400 <= 599
title
required

A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.

string
traceId
required

W3C trace ID of the failed request.

string
type
required

https://fedwright.com/problems/{code}, the same in every environment.

string format: uri

Example generated

{
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"instance": "example",
"limit": "example",
"resetsAt": "2026-04-15T12:00:00Z",
"status": 1,
"title": "example",
"traceId": "example",
"type": "https://example.com"
}

The Problem type says which check refused the caller, when that is about the caller’s own token, client, or role: insufficient-scope when the token’s scopes (or an MCP grant’s) lack the operation’s scope, with WWW-Authenticate: Bearer error="insufficient_scope", scope="..." (RFC 6750) naming the missing scopes; client-not-allowed when the operation doesn’t admit the caller’s kind of client, such as a machine client calling a user-only operation; and insufficient-role when a confirmed member’s roles don’t allow the action. Any other refusal is the generic forbidden, which says nothing more. Another organization’s resource is 404 (not-found) instead, so no reason confirms that it exists. An owner or administrator who sent no proof of a second factor gets mfa-required. An operation that needs an active subscription, when the organization has none, returns subscription-inactive, or organization-suspended when Fedwright suspended the organization. A suspended organization also refuses invitations, new joins through an invitation, and role changes with organization-suspended. Creating or joining an organization without a verified email returns email-unverified, and accepting an invitation sent to another address returns invitation-email-mismatch. A request from Fedwright’s web or mobile app whose session acts for no organization yet returns organization-required, except on getMe, createOrganization, and acceptInvitation. Shared data needs the acting organization’s own subscription; another organization’s doesn’t count.

Media typeapplication/problem+json

RFC 9457 Problem Details.

object
detail

An explanation specific to this occurrence of the problem. It is absent for server errors.

string
errors

Validation errors, by field path.

object
key
additional properties
Array<string>
instance

A URI reference that identifies this occurrence of the problem, when the API provides one.

string
limit

On rate-limited, the quota that is used up, such as org-day. On premium-quota-exceeded, org-premium-day. A 429 with an empty body does not name it.

string
resetsAt

On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.

string format: date-time
status
required

The HTTP status code of the response, from 400 to 599.

integer
>= 400 <= 599
title
required

A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.

string
traceId
required

W3C trace ID of the failed request.

string
type
required

https://fedwright.com/problems/{code}, the same in every environment.

string format: uri

Example generated

{
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"instance": "example",
"limit": "example",
"resetsAt": "2026-04-15T12:00:00Z",
"status": 1,
"title": "example",
"traceId": "example",
"type": "https://example.com"
}

The request is well formed and its schema accepts it, but it breaks a rule beyond the schema, such as an unknown NAICS code (Problem type validation-failed, with errors by field path). An Idempotency-Key already used for another request returns idempotency-key-reused.

Media typeapplication/problem+json

RFC 9457 Problem Details.

object
detail

An explanation specific to this occurrence of the problem. It is absent for server errors.

string
errors

Validation errors, by field path.

object
key
additional properties
Array<string>
instance

A URI reference that identifies this occurrence of the problem, when the API provides one.

string
limit

On rate-limited, the quota that is used up, such as org-day. On premium-quota-exceeded, org-premium-day. A 429 with an empty body does not name it.

string
resetsAt

On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.

string format: date-time
status
required

The HTTP status code of the response, from 400 to 599.

integer
>= 400 <= 599
title
required

A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.

string
traceId
required

W3C trace ID of the failed request.

string
type
required

https://fedwright.com/problems/{code}, the same in every environment.

string format: uri

Example generated

{
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"instance": "example",
"limit": "example",
"resetsAt": "2026-04-15T12:00:00Z",
"status": 1,
"title": "example",
"traceId": "example",
"type": "https://example.com"
}

A rate limit is used up. Direct API access counts against the organization’s burst, daily, and monthly quotas, which all its machine clients share; there is no client quota. A 429 comes in two shapes with two header families, so read the response by what it carries.

A machine client’s calls can get a 429 with an empty body. It has three headers: X-RateLimit-Limit, the exhausted rule’s limit and window, such as 3000, 3000;w=2592000; X-RateLimit-Remaining, what is left in that window (0 on a 429); and X-RateLimit-Reset, the seconds until that window resets. It has no Retry-After, no RateLimit headers, no Problem, and does not name the quota. Read the quota from the window w:

w (seconds) Quota
60 Burst.
86400 Daily.
2592000 Monthly (the calendar month is reported as 30 days; X-RateLimit-Reset is exact).

Wait X-RateLimit-Reset seconds before you retry. Refused requests still count: a client that keeps calling after a 429 keeps adding to the counter, so it does not regain budget inside the window. A tier change takes effect within 10 minutes (checkout, the billing portal, and grants alike), once the client gets a new access token.

Every other 429 has a Problem and Retry-After. The Problem type is rate-limited for a used-up quota, or, for an ask, ai-budget-exceeded or premium-quota-exceeded (below). On rate-limited, Retry-After is the seconds until the used-up limit’s window resets, the latest if several are. The Problem also carries limit, the quota that is used up (the one that resets last, if several are), resetsAt, when it starts again, and traceId. RateLimit-Policy and RateLimit describe only the caller’s own limits, here and on every other response a limit applies to. A request refused with rate-limited uses no quota. One refused after that check, for its scope, role, subscription, or kind of client, still counts, so once a quota is used up such a request gets 429 instead of its 403. A request that fails authentication is not counted. An ask that the organization’s AI spending budget can’t cover returns ai-budget-exceeded instead, with Retry-After at the end of the budget’s window: that budget counts what asks cost, not how many there are. An ask that the organization’s premium units for the day can’t cover returns premium-quota-exceeded, with limit (org-premium-day), resetsAt (the next midnight UTC), and Retry-After. That is the plan’s allowance: a plan with no premium units never covers an ask, and a higher plan may. A refused ask uses no units.

Media typeapplication/problem+json

RFC 9457 Problem Details.

object
detail

An explanation specific to this occurrence of the problem. It is absent for server errors.

string
errors

Validation errors, by field path.

object
key
additional properties
Array<string>
instance

A URI reference that identifies this occurrence of the problem, when the API provides one.

string
limit

On rate-limited, the quota that is used up, such as org-day. On premium-quota-exceeded, org-premium-day. A 429 with an empty body does not name it.

string
resetsAt

On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.

string format: date-time
status
required

The HTTP status code of the response, from 400 to 599.

integer
>= 400 <= 599
title
required

A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.

string
traceId
required

W3C trace ID of the failed request.

string
type
required

https://fedwright.com/problems/{code}, the same in every environment.

string format: uri

Examples

An ask the premium units can't cover

{
"limit": "org-premium-day",
"resetsAt": "2026-11-08T00:00:00Z",
"status": 429,
"title": "Too Many Requests",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"type": "https://fedwright.com/problems/premium-quota-exceeded"
}
RateLimit
string

For each limit in RateLimit-Policy, the requests r its window still allows and the seconds t until the window resets, such as "org-burst";r=7;t=40, "org-day";r=62;t=41000.

RateLimit-Policy
string

The caller’s rate limits, in the IETF HTTPAPI RateLimit header fields: each limit’s name, its quota q, and its window w in seconds, such as "org-burst";q=20;w=60, "org-day";q=100;w=86400.

Retry-After
integer

Seconds to wait before retrying.

X-RateLimit-Limit
string

On a 429 with an empty body (and on the successful responses that carry these headers), the exhausted rule’s limit and window w in seconds, such as 3000, 3000;w=2592000. The window names the quota: 60 is burst, 86400 is daily, and 2592000 is monthly.

X-RateLimit-Remaining
integer

What is left in that rule’s window (0 on a 429).

X-RateLimit-Reset
integer

Seconds until that rule’s window resets.

Search is temporarily unavailable (Problem type search-unavailable), for example while the requested history is still building. Retry after the indicated number of seconds.

Media typeapplication/problem+json

RFC 9457 Problem Details.

object
detail

An explanation specific to this occurrence of the problem. It is absent for server errors.

string
errors

Validation errors, by field path.

object
key
additional properties
Array<string>
instance

A URI reference that identifies this occurrence of the problem, when the API provides one.

string
limit

On rate-limited, the quota that is used up, such as org-day. On premium-quota-exceeded, org-premium-day. A 429 with an empty body does not name it.

string
resetsAt

On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.

string format: date-time
status
required

The HTTP status code of the response, from 400 to 599.

integer
>= 400 <= 599
title
required

A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.

string
traceId
required

W3C trace ID of the failed request.

string
type
required

https://fedwright.com/problems/{code}, the same in every environment.

string format: uri

Example generated

{
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"instance": "example",
"limit": "example",
"resetsAt": "2026-04-15T12:00:00Z",
"status": 1,
"title": "example",
"traceId": "example",
"type": "https://example.com"
}
Retry-After
integer

Seconds to wait before retrying.

Any other error. A request body over 64 KiB returns 413 (payload-too-large), and a request that takes longer than 10 seconds (90 for askOpportunities) returns 503 (request-timeout). An invitation when the API can’t send mail returns 503 (mail-unavailable), and creates nothing. An unexpected failure returns 500 (internal-error) with only type, title, status, and traceId.

Media typeapplication/problem+json

RFC 9457 Problem Details.

object
detail

An explanation specific to this occurrence of the problem. It is absent for server errors.

string
errors

Validation errors, by field path.

object
key
additional properties
Array<string>
instance

A URI reference that identifies this occurrence of the problem, when the API provides one.

string
limit

On rate-limited, the quota that is used up, such as org-day. On premium-quota-exceeded, org-premium-day. A 429 with an empty body does not name it.

string
resetsAt

On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.

string format: date-time
status
required

The HTTP status code of the response, from 400 to 599.

integer
>= 400 <= 599
title
required

A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.

string
traceId
required

W3C trace ID of the failed request.

string
type
required

https://fedwright.com/problems/{code}, the same in every environment.

string format: uri

Example generated

{
"detail": "example",
"errors": {
"additionalProperty": [
"example"
]
},
"instance": "example",
"limit": "example",
"resetsAt": "2026-04-15T12:00:00Z",
"status": 1,
"title": "example",
"traceId": "example",
"type": "https://example.com"
}