Attestation workflow

When a registry flags one of your contacts for verification, follow this workflow to identify the affected domains, review the required claims, and submit attestations through the API.

For background on verification concepts (claims, methods, proofs, deadlines), see the Contact verification overview.

Flow overview

  1. Identify domains and contacts requiring verification.
  2. Check which claims need to be attested for the affected contact.
  3. Submit attestations with the appropriate method, proof, and reference.
  4. Confirm the attestation result and track status tag removal.

1. Identify affected domains and contacts

When verification is required, both the affected domains and contacts are tagged with VERIFICATION_REQUIRED. Domains also include a verification_required field in their response containing the specific claims and deadlines.

Filter domains by status tag

List all domains currently requiring verification:

curl --get "$OPUSDNS_API_BASE/v1/domains" \
  --header "X-Api-Key: $OPUSDNS_API_KEY" \
  --data-urlencode "status_tags=VERIFICATION_REQUIRED"

Filter contacts by status tag

List all contacts currently requiring verification:

curl --get "$OPUSDNS_API_BASE/v1/contacts" \
  --header "X-Api-Key: $OPUSDNS_API_KEY" \
  --data-urlencode "status_tags=VERIFICATION_REQUIRED" \
  --data-urlencode "include=tags"

The response includes a status_tags field on each contact when include=tags is specified:

{
  "contact_id": "contact_01jxe1nzrmf78scaqbkjx0va0f",
  "first_name": "Jane",
  "last_name": "Smith",
  "status_tags": [
    {
      "label": "VERIFICATION REQUIRED",
      "type": "VERIFICATION_REQUIRED"
    }
  ]
}

You can combine status_tags with status_tag_mode (match_any or match_all) to control how multiple status tag filters are combined.

Check the verification_required field on domains

Every domain response includes a verification_required field. When verification is needed, it contains the pending claims and deadlines. When no verification is required, it is null.

curl "$OPUSDNS_API_BASE/v1/domains/example.de" \
  --header "X-Api-Key: $OPUSDNS_API_KEY"
{
  "domain_id": "domain_01jxe1nzrmf78scaqbkjx0va0f",
  "name": "example.de",
  "verification_required": {
    "claims": ["email", "name", "address"],
    "deadlines": [
      {
        "type": "dedelegation",
        "date": "2026-07-15T00:00:00Z"
      },
      {
        "type": "deletion",
        "date": "2026-08-15T00:00:00Z"
      }
    ]
  }
}

When no verification is pending, the field is null:

{
  "domain_id": "domain_01jxe1nzrmf78scaqbkjx0va0f",
  "name": "example.de",
  "verification_required": null
}

Verification fields

Field Type Description
verification_required object | null Present when verification is required, null otherwise.
verification_required.claims string[] Identity claims that require verification. Values: name, address, email, phone.
verification_required.deadlines object[] Registry-imposed deadlines with consequences if verification is not completed.
verification_required.deadlines[].type string dedelegation — DNS stops resolving. deletion — domain is permanently removed.
verification_required.deadlines[].date string ISO 8601 UTC timestamp of the deadline.

2. Check verification status

Retrieve the current verification state for a contact. This returns the status of each individual claim:

curl "$OPUSDNS_API_BASE/v1/contacts/$CONTACT_ID/verifications" \
  --header "X-Api-Key: $OPUSDNS_API_KEY"

Response

{
  "verifications": [
    {
      "claim": "NAME",
      "state": "VERIFIED",
      "method": "PHYSICAL_DOCUMENT",
      "proof": "PASSPORT",
      "attestation_reference": "REF-2026-001",
      "verified_on": "2026-05-10T14:30:00Z",
      "expires_on": "2027-05-10T14:30:00Z"
    },
    {
      "claim": "ADDRESS",
      "state": "UNVERIFIED",
      "method": null,
      "proof": null,
      "attestation_reference": null,
      "verified_on": null,
      "expires_on": null
    },
    {
      "claim": "EMAIL",
      "state": "IN_PROGRESS",
      "method": "REACHABILITY",
      "proof": "EMAIL_VER_TRANSACTION_LOG",
      "attestation_reference": "email-verif-20260518",
      "verified_on": null,
      "expires_on": null
    }
  ]
}

Error responses

Status Meaning
404 Contact has not yet been flagged for verification. This typically means verification has not been initiated for this contact.
502 The verification service is temporarily unavailable. Retry later.

3. Submit attestations

Submit one or more attestations to verify identity claims for a contact:

curl "$OPUSDNS_API_BASE/v1/contacts/$CONTACT_ID/verifications/attest" \
  --request POST \
  --header "X-Api-Key: $OPUSDNS_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "attestations": [
      {
        "claim": "NAME",
        "method": "PHYSICAL_DOCUMENT",
        "proof": "PASSPORT",
        "attestation_reference": "REF-2026-001"
      },
      {
        "claim": "ADDRESS",
        "method": "PHYSICAL_DOCUMENT",
        "proof": "PASSPORT",
        "attestation_reference": "REF-2026-001"
      }
    ]
  }'

Request fields

Field Required Description
attestations Yes Array of attestation objects (max 50 per request).
attestations[].claim Yes The claim being verified. See Claims.
attestations[].method Yes How the claim is being verified. See Methods.
attestations[].proof Yes The specific evidence type used. See Proofs.
attestations[].attestation_reference Yes Your reference identifier for the attestation (max 255 characters).

Registry-specific constraints

Some registries impose extra rules on top of the request format above. These constraints apply only when the contact is a registrant on domains of that TLD that currently require verification — for every other TLD, the standard request format applies.

TLD Registry Constraint
.de DENIC All attestations in a single request must share the same method, proof, and attestation_reference. Submit one request per method/proof combination if the claims need different ones.

Violating a registry-specific constraint rejects the entire request — no attestation in it is submitted. Check the table above before batching attestations for a contact.

Response

The response returns the updated verification state for all claims — same format as the GET endpoint.

Error responses

Status Code Meaning
400 ERROR_DOMAIN_VERIFICATION_INCONSISTENT_METHOD_PROOF Multiple attestations in one request use different methods or proofs, which the registry does not allow. See Registry-specific constraints.
404 ERROR_CONTACT_VERIFICATION_UPSTREAM_NOT_FOUND Contact has not been registered for verification.
502 ERROR_CONTACT_VERIFICATION_UPSTREAM_ERROR Verification service temporarily unavailable.

4. After attestation

The attest endpoint returns the updated verification state for all claims directly in the response. You can immediately see whether each claim moved to VERIFIED or IN_PROGRESS.

Once all claims reach the VERIFIED state, the registry clears the deadlines. OpusDNS automatically:

  • Removes the VERIFICATION_REQUIRED status tag from:
    • the contact: immediately after successful attestation
    • affected domains: on the next domain sync.
  • Sets verification_required to null on affected domain responses.

If any claims are still IN_PROGRESS after attestation (awaiting registry confirmation), you can check back later using the GET endpoint:

curl "$OPUSDNS_API_BASE/v1/contacts/$CONTACT_ID/verifications" \
  --header "X-Api-Key: $OPUSDNS_API_KEY"

You can also monitor verification-related events through the events API:

curl --get "$OPUSDNS_API_BASE/v1/events" \
  --header "X-Api-Key: $OPUSDNS_API_KEY" \
  --data-urlencode "object_type=CONTACT" \
  --data-urlencode "type=VERIFICATION"

By default, the events API returns only pending (unacknowledged) events. Pass acknowledged=true to list events you have already acknowledged.

Troubleshooting

Issue Cause Resolution
404 on GET verification status Contact hasn't been flagged for verification yet. Wait for the verification process to initialize, or check that you're using the correct contact ID.
400 inconsistent method/proof Multiple attestations use different methods or proofs in one request (.de restriction). Submit separate requests — one per method/proof combination. See Registry-specific constraints.
Claims stuck in IN_PROGRESS Registry hasn't confirmed the attestation yet. Wait and poll again. Registry confirmation can take time.
Contact tag removed but domain tag remains Contact tag is removed immediately after attestation; domain tags are cleared on the next sync cycle. Wait a few minutes for the domain sync to run.
verification_required still present after VERIFIED Domain hasn't synced yet. The field is cleared on the next domain sync cycle. This typically happens within minutes.

Next steps