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-Account when you act on a child Account. Definitions belong to the Account that creates them.
  • Scopes: payments.requirement-definition:read and payments.requirement-definition:write.
  • For types backed by a configuration, the dataSourceId of a template your Account owns, such as a document template.

Endpoints

Method and pathOperation
POST /v3/onboarding/requirement-definitionscreateRequirementDefinition
GET /v3/onboarding/requirement-definitionslistRequirementDefinitions
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}/activateactivateRequirementDefinition
POST /v3/onboarding/requirement-definitions/{requirementDefinitionId}/deactivatedeactivateRequirementDefinition

Send an Idempotency-Key on every POST and PATCH.

Create a definition

name and type are required.

FieldNotes
typeRegistration, PayoutMethod, TaxVerification, Signature (alias SignatureRequest), DocumentUpload, BackgroundCheck, Insurance (alias InsuranceCoverage), ExternalCompletion, BiometricIdentityVerification, or EmploymentEligibilityVerification. EmployeeTaxForms is created by Wingspan and returns 422.
dataSourceIdThe 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, metadataFree text and your key-value data.
externalIdYour reconciliation id, unique per Account.
reviewPolicyNeverRequired (default), AlwaysRequired, or OnFail.
expirationStrategy, expirationDaysHow 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, daysUntilExpirationGrace window and legacy expiry window, in days from provisioning. Create only. daysUntilEffective must be less than daysUntilExpiration.
manualRenewalAllowedWhether 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].

FilterOperators
typein (or anyOf), and notIn (or noneOf) to exclude.
externalIdeq, in, anyOf.
dataSourceIdeq, in, anyOf. Finds the definitions that use a template.
statusin 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 fieldValues
scopeNewOnly (default), IncompleteAndNew, or All.
strategyRenewal (default), or Immediate.
expiresAtDate-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 .../deactivate archives the definition (status: Inactive). Nothing is deleted.
  • POST .../activate restores an archived definition to Active.
  • DELETE .../{requirementDefinitionId} removes it permanently and returns 204. A definition attached to active Engagements can't be deleted and returns 409.

Use deactivate when you may want the definition back.

Errors

StatusWhen
400A malformed request.
401, 403No valid credential, or a missing scope.
404No definition with that id in your scope, or a dataSourceId your Account doesn't own.
409A duplicate externalId on create, a second singleton definition, or a delete of a definition attached to active Engagements.
422Invalid field values, EmployeeTaxForms on create, a rejected legacy field, or dataSourceId on a type that has none.

Related pages


Did this page help you?