Requirement definitions
Create, list, read, update, delete, activate, and deactivate requirement definitions with the Wingspan V3 API.
A requirement definition is a reusable template for something a Payee must complete, such as signing a document, uploading a license, or passing a background check. Attach a definition to an Engagement to require it. For the end-to-end flow, see Requirements and eligibility. To bundle definitions, see Requirement definition groups.
Prerequisites
- An Account credential. Use
X-Wingspan-Accountwhen you act on a child Account. Definitions belong to the Account that creates them. - Scopes:
payments.requirement-definition:readandpayments.requirement-definition:write. - For types backed by a configuration, the
dataSourceIdof a template your Account owns, such as a document template.
Endpoints
| Method and path | Operation |
|---|---|
POST /v3/onboarding/requirement-definitions | createRequirementDefinition |
GET /v3/onboarding/requirement-definitions | listRequirementDefinitions |
GET /v3/onboarding/requirement-definitions/{requirementDefinitionId} | getRequirementDefinition |
PATCH /v3/onboarding/requirement-definitions/{requirementDefinitionId} | updateRequirementDefinition |
DELETE /v3/onboarding/requirement-definitions/{requirementDefinitionId} | deleteRequirementDefinition |
POST /v3/onboarding/requirement-definitions/{requirementDefinitionId}/activate | activateRequirementDefinition |
POST /v3/onboarding/requirement-definitions/{requirementDefinitionId}/deactivate | deactivateRequirementDefinition |
Send an Idempotency-Key on every POST and PATCH.
Create a definition
name and type are required.
| Field | Notes |
|---|---|
type | Registration, PayoutMethod, TaxVerification, Signature (alias SignatureRequest), DocumentUpload, BackgroundCheck, Insurance (alias InsuranceCoverage), ExternalCompletion, BiometricIdentityVerification, or EmploymentEligibilityVerification. EmployeeTaxForms is created by Wingspan and returns 422. |
dataSourceId | The template instances are created from. Required for Signature, DocumentUpload, BackgroundCheck, and Insurance. Other types reject it with 422. A template your Account doesn't own returns 404. |
description, metadata | Free text and your key-value data. |
externalId | Your reconciliation id, unique per Account. |
reviewPolicy | NeverRequired (default), AlwaysRequired, or OnFail. |
expirationStrategy, expirationDays | How long a completed requirement stays valid. Strategies: DaysAfterComplete (default when expirationDays is set; at least 30 days), DaysAfterYearStart, DaysBeforeYearEnd, None. Any strategy other than None needs expirationDays. |
daysUntilEffective, daysUntilExpiration | Grace window and legacy expiry window, in days from provisioning. Create only. daysUntilEffective must be less than daysUntilExpiration. |
manualRenewalAllowed | Whether a payer or payee can renew an instance by hand. |
Each Account can have one BiometricIdentityVerification definition and one EmploymentEligibilityVerification definition. A second returns 409.
The fields isBlocking, isPayeeActionRequired, isPayerActionRequired, source, passingValues, and policy are legacy. The V3 API rejects them. Use type, reviewPolicy, and the Engagement's blockingMode.
curl -X POST https://api.wingspan.app/v3/onboarding/requirement-definitions \
-H "Authorization: Bearer $WINGSPAN_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Sign the 2026 NDA",
"type": "Signature",
"dataSourceId": "t1erTOHO7rlJI7nzF8uCpY",
"reviewPolicy": "NeverRequired",
"expirationDays": 365,
"externalId": "REQ-NDA-2026"
}'The 201 response is the definition. The values in the example are illustrative.
{
"id": "oP8lYOzdKQy7H_mNrx9Uf9",
"name": "Sign the 2026 NDA",
"type": "Signature",
"status": "Active",
"version": 1,
"dataSourceId": "t1erTOHO7rlJI7nzF8uCpY",
"reviewPolicy": "NeverRequired",
"expirationDays": 365
}Create isn't an upsert. A duplicate externalId returns 409 ResourceConflict. To recover, list with filter[externalId][eq].
List and read
GET /v3/onboarding/requirement-definitions takes page[size] and page[token].
| Filter | Operators |
|---|---|
type | in (or anyOf), and notIn (or noneOf) to exclude. |
externalId | eq, in, anyOf. |
dataSourceId | eq, in, anyOf. Finds the definitions that use a template. |
status | in or anyOf: Active, Inactive. |
Sort with sort[updatedAt]=asc or desc. pagination.totalSize counts the filtered results, so you can show active and archived counts.
curl -g "https://api.wingspan.app/v3/onboarding/requirement-definitions?filter[status][in][]=Active&filter[type][in][]=Signature" \
-H "Authorization: Bearer $WINGSPAN_TOKEN"GET .../{requirementDefinitionId} returns one definition. Add ?expand[]=DataSource to inline the backing configuration in dataSource. Expansion isn't available on list rows.
A definition also returns these read-only fields: status, version, minVersion, versionScope, versionCreatedAt, versionNote, versionTransitionStrategy, versionTransitionExpiresAt, versionHistory, events, and actors.
Update a definition
PATCH is a JSON Merge Patch. Send only the fields to change: name, description, dataSourceId, manualRenewalAllowed, expirationStrategy, expirationDays, reviewPolicy, metadata, versionNote, and transition. daysUntilEffective and daysUntilExpiration are create-only.
Wingspan decides whether a change is material. A material change, such as pointing dataSourceId at a new template, publishes a new version. transition controls how existing instances pick it up:
transition field | Values |
|---|---|
scope | NewOnly (default), IncompleteAndNew, or All. |
strategy | Renewal (default), or Immediate. |
expiresAt | Date-time. The deadline to move over when strategy is Renewal. |
An immaterial change doesn't raise version or reopen existing instances. dataSourceId returns 422 for a type that has no data source and 404 for a template your Account doesn't own.
curl -X PATCH https://api.wingspan.app/v3/onboarding/requirement-definitions/$DEFINITION_ID \
-H "Authorization: Bearer $WINGSPAN_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"dataSourceId": "Hq3mVx8TnC5wPd2ZrL7bKe",
"versionNote": "Updated NDA wording",
"transition": { "scope": "IncompleteAndNew", "strategy": "Immediate" }
}'Deactivate, activate, and delete
POST .../deactivatearchives the definition (status: Inactive). Nothing is deleted.POST .../activaterestores an archived definition toActive.DELETE .../{requirementDefinitionId}removes it permanently and returns204. A definition attached to active Engagements can't be deleted and returns409.
Use deactivate when you may want the definition back.
Errors
| Status | When |
|---|---|
400 | A malformed request. |
401, 403 | No valid credential, or a missing scope. |
404 | No definition with that id in your scope, or a dataSourceId your Account doesn't own. |
409 | A duplicate externalId on create, a second singleton definition, or a delete of a definition attached to active Engagements. |
422 | Invalid field values, EmployeeTaxForms on create, a rejected legacy field, or dataSourceId on a type that has none. |
Related pages
Updated 12 minutes ago