List matches
const url = 'https://api-staging.fedwright.com/v1/orgs/019aa3f2-6d10-7b20-9c4f-7e2d3cad5b12/matches?limit=50&status=active&sort=-score';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api-staging.fedwright.com/v1/orgs/019aa3f2-6d10-7b20-9c4f-7e2d3cad5b12/matches?limit=50&status=active&sort=-score' \ --header 'Authorization: Bearer <token>'Threads that match the organization, best first by default. state is
the caller’s own state for each match.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”A UUIDv7.
The organization. The caller must be a member; otherwise the response is 404, as if it didn’t exist.
Query Parameters
Section titled “Query Parameters”Maximum number of items to return.
Opaque cursor from a previous response’s nextCursor.
Only items Fedwright first saw at or after this time (firstSeenAt).
Default active.
Grades to include; repeat for several.
The caller’s own states to include. Repeat the parameter for several.
One of: score, createdAt, deadline. A leading - sorts descending. Default -score.
Responses
Section titled “Responses”A page of matches.
object
Cursor for the next page, or null on the last page.
An organization’s match to a procurement thread: its score, the reasons for it, and the caller’s state. The detail operation also returns the score history.
object
What the score was computed from. raw means the notice as published, and enriched means the notice after enrichment added derived fields.
The weighted components that make up the score.
One weighted score component.
object
Matched code, program, labels, saved search IDs, or cosine, as appropriate.
Which part of the fit the component measures.
How the component enters the score. A ready component is counted at its measured value. A pending component is counted at a provisional value because an input is not available yet. A notApplicable component does not apply to the organization’s profile and is left out of the score.
How well the notice fits this component, from 0 (no fit) to 1 (full fit).
The component’s weight in the score, from 0 to 100. A larger weight moves the score more.
When the match was first created.
The score band, from A (best) to D.
The reasons the thread matched, such as a matching code, set-aside, or place.
One reason a thread matched.
object
A short, human-readable explanation of the reason.
The kind of reason.
The value that matched, such as a NAICS or PSC code, a set-aside code, or a keyword. Its form depends on type.
The version of the scoring rules that produced the score. A score keeps the version that made it.
The IDs of the organization’s saved searches that matched the thread.
The match score as a whole number from 0 to 100, higher being a better fit. It is the weighted average of the components that apply.
Present on getMatch, oldest score first.
A score for one notice version, oldest first in score history.
object
What the score was computed from. raw means the notice as published, and enriched means the notice after enrichment added derived fields.
The weighted components that make up the score.
One weighted score component.
object
Matched code, program, labels, saved search IDs, or cosine, as appropriate.
Which part of the fit the component measures.
How the component enters the score. A ready component is counted at its measured value. A pending component is counted at a provisional value because an input is not available yet. A notApplicable component does not apply to the organization’s profile and is left out of the score.
How well the notice fits this component, from 0 (no fit) to 1 (full fit).
The component’s weight in the score, from 0 to 100. A larger weight moves the score more.
The notice fields that changed from the previous version. Present only when the score followed a change.
One changed field. rule identifies the rule that set its significance. Long values, such as descriptions
and contacts, are left out (valuesOmitted); the notice and its
versions hold them.
object
The normalized field, as a dotted path.
The value after the change. Any JSON value.
The value before the change. Any JSON value.
The change makes the matcher re-check the thread.
The change rule that set the field’s significance.
How much a change matters to a responder: high, medium, or low.
True when the values are left out because they are long, such as a description or contacts.
The score band, from A (best) to D.
SAM.gov NoticeId.
The version of the scoring rules that produced the score.
The match score as a whole number from 0 to 100.
When the score was computed.
The version number of the notice that was scored.
SAM.gov NoticeId.
The version number of the notice that the score was computed for.
What produced the match: profile for the organization’s company profile and savedSearch for a saved search. A match can have both.
A user’s own state for a match.
A match that stops fitting after a change is marked, not deleted.
A solicitation thread. Derived from its notices, never edited by hand.
object
The number of award notices in the thread.
object
The deadline as a point in time, or null when SAM.gov gave a date without a time.
The deadline’s date, or null when SAM.gov gave a time as well.
True when SAM.gov gave a time as well as a date.
The NAICS code of the latest notice, or null when it has none.
The PSC code of the latest notice, or null when it has none.
The set-aside of the latest notice.
object
The SAM.gov set-aside code, or null when none is set.
The set-aside programs the code belongs to. Empty when none is set.
True when the set-aside is a sole-source code.
SAM.gov notice type, using its published label.
The normalized key of the issuing department, or null when the notices name none.
When SAM.gov posted the thread’s first notice.
When Fedwright first saw any notice of the thread.
Opaque thread identifier; use the ID the API returns.
When the thread last changed. Before any change, it is when Fedwright first saw the thread.
The latest change to a procurement thread.
object
A UUIDv7.
What the change was. A change can have more than one kind.
When the change occurred.
How much a change matters to a responder: high, medium, or low.
SAM.gov NoticeId.
The number of notices in the thread.
The stage as users see it: solicitation becomes open while the
deadline is in the future or missing, and closed once it has passed.
Calculated when the response is built.
A Justification or J&A notice has joined the thread.
The latest notice’s solicitation number, as given.
The normalized solicitation number the thread is keyed on, or null for a thread with none.
The stage stored on a thread.
Opaque thread identifier; use the ID the API returns.
SAM.gov NoticeId.
When the match last changed.
Examples
A page of matches
{ "items": [ { "basis": "enriched", "components": [ { "detail": "336413", "id": "codes", "state": "ready", "value": 1, "weight": 30 }, { "detail": "unrestricted", "id": "setAside", "state": "ready", "value": 0.5, "weight": 15 }, { "detail": null, "id": "preference", "state": "notApplicable", "value": 0, "weight": 10 }, { "detail": "OH", "id": "place", "state": "ready", "value": 1, "weight": 10 }, { "detail": [ "aerospace" ], "id": "labels", "state": "ready", "value": 0.5, "weight": 10 }, { "detail": null, "id": "keywords", "state": "notApplicable", "value": 0, "weight": 10 }, { "detail": 0.46, "id": "capability", "state": "ready", "value": 0.7, "weight": 15 } ], "createdAt": "2026-10-02T03:44:20Z", "grade": "B", "reasons": [ { "label": "Other Aircraft Parts and Auxiliary Equipment Manufacturing", "type": "naics", "value": "336413" }, { "label": "Aerospace Craft and Structural Components", "type": "psc", "value": "15" } ], "rulesVersion": "v1", "savedSearchIds": [], "score": 79, "scoredNoticeId": "e6a41be9630d4261b6f3131923fdc4ce", "scoredVersion": 1, "sources": [ "profile" ], "state": "starred", "status": "active", "thread": { "awardCount": 0, "currentDeadline": { "at": "2026-11-02T20:30:00Z", "date": null, "hasTime": true }, "currentNaics": "336413", "currentPsc": "1560", "currentSetAside": { "code": null, "programs": [], "soleSource": false }, "currentType": "Solicitation", "departmentKey": "DEPTOFDEFENSE", "firstPostedAt": "2026-09-17T12:44:56Z", "firstSeenAt": "2026-10-02T03:41:07Z", "id": "DEPTOFDEFENSE:N0038326QFC09", "lastChangedAt": "2026-10-03T03:41:12Z", "latestChange": { "id": "019aa3f2-6d10-7b20-9c4f-7e2d3cad5b12", "kinds": [ "amended" ], "occurredAt": "2026-10-03T03:41:12Z", "significance": "high" }, "latestNoticeId": "e6a41be9630d4261b6f3131923fdc4ce", "noticeCount": 2, "phase": "open", "soleSourceJustified": false, "solicitationDisplay": "N0038326QFC09", "solicitationKey": "N0038326QFC09", "stage": "solicitation" }, "threadId": "DEPTOFDEFENSE:N0038326QFC09", "triggeringNoticeId": "e6a41be9630d4261b6f3131923fdc4ce", "updatedAt": "2026-10-03T03:44:51Z" } ], "nextCursor": 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.
RFC 9457 Problem Details.
object
An explanation specific to this occurrence of the problem. It is absent for server errors.
Validation errors, by field path.
object
A URI reference that identifies this occurrence of the problem, when the API provides one.
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.
On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.
The HTTP status code of the response, from 400 to 599.
A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.
W3C trace ID of the failed request.
https://fedwright.com/problems/{code}, the same in every environment.
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.
RFC 9457 Problem Details.
object
An explanation specific to this occurrence of the problem. It is absent for server errors.
Validation errors, by field path.
object
A URI reference that identifies this occurrence of the problem, when the API provides one.
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.
On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.
The HTTP status code of the response, from 400 to 599.
A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.
W3C trace ID of the failed request.
https://fedwright.com/problems/{code}, the same in every environment.
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.
RFC 9457 Problem Details.
object
An explanation specific to this occurrence of the problem. It is absent for server errors.
Validation errors, by field path.
object
A URI reference that identifies this occurrence of the problem, when the API provides one.
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.
On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.
The HTTP status code of the response, from 400 to 599.
A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.
W3C trace ID of the failed request.
https://fedwright.com/problems/{code}, the same in every environment.
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 resource does not exist, or belongs to another organization.
RFC 9457 Problem Details.
object
An explanation specific to this occurrence of the problem. It is absent for server errors.
Validation errors, by field path.
object
A URI reference that identifies this occurrence of the problem, when the API provides one.
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.
On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.
The HTTP status code of the response, from 400 to 599.
A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.
W3C trace ID of the failed request.
https://fedwright.com/problems/{code}, the same in every environment.
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.
RFC 9457 Problem Details.
object
An explanation specific to this occurrence of the problem. It is absent for server errors.
Validation errors, by field path.
object
A URI reference that identifies this occurrence of the problem, when the API provides one.
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.
On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.
The HTTP status code of the response, from 400 to 599.
A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.
W3C trace ID of the failed request.
https://fedwright.com/problems/{code}, the same in every environment.
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"}A quota used up
{ "limit": "org-day", "resetsAt": "2026-11-08T00:00:00Z", "status": 429, "title": "Too Many Requests", "traceId": "4bf92f3577b34da6a3ce929d0e0e4736", "type": "https://fedwright.com/problems/rate-limited"}Headers
Section titled “Headers”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.
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.
Seconds to wait before retrying.
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.
What is left in that rule’s window (0 on a 429).
Seconds until that rule’s window resets.
default
Section titled “default”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.
RFC 9457 Problem Details.
object
An explanation specific to this occurrence of the problem. It is absent for server errors.
Validation errors, by field path.
object
A URI reference that identifies this occurrence of the problem, when the API provides one.
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.
On rate-limited from the API and on premium-quota-exceeded, when that quota starts again.
The HTTP status code of the response, from 400 to 599.
A short, human-readable summary of the problem. Use type to identify the kind of problem, not this text.
W3C trace ID of the failed request.
https://fedwright.com/problems/{code}, the same in every environment.
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"}