Skip to main content

Working with Children Checks (WWC)

This comprehensive guide shows you how to integrate Working with Children (WWC) checks across all Australian states and territories using the Oho API.

Overview

The /api/scan endpoint provides a unified interface for submitting Working With Children (WWC) credential validations across all Australian states and territories. Validations are processed asynchronously - the endpoint queues the request and returns immediately with a correlation_id for tracking. Results are delivered later via webhook.

This universal endpoint accepts a consistent payload structure across all states, with the type field specifying which state registry to validate against. This approach eliminates the need to maintain separate integration code for each state.

Base URL: POST /api/scan

Authentication: Required (Bearer token)

Content-Type: application/json

Key Benefits:

  • ✅ Single endpoint for all Australian states and territories
  • ✅ Consistent payload structure across all WWC types
  • ✅ Asynchronous processing for high performance
  • ✅ Built-in retry logic and webhook delivery

Understanding State Capabilities

Before integrating WWC verification, it's important to understand that capabilities vary significantly by state. This affects verification speed, monitoring frequency, and available features.

Quick Capability Overview

StateVerification SpeedMonitoring FrequencyEmployer LinkageRenewal Auto-Updates
VIC<10 secondsWeeklyNo (employee responsibility)Yes
NSWHoursAnnual + direct OCG alertsYes (automatic)Yes
QLD<10 secondsWeeklyYes (manual)No
SA<10 minutesWeeklyYes (automatic)Yes
WA<10 secondsWeeklyNoYes
TAS<10 minutesWeeklyNoYes
NT<10 minutesWeeklyNoYes
ACTMonthly (manual)MonthlyNoYes
Need Detailed Capability Information?

See the WWCC Capability Reference for detailed scenarios including:

  • Verification timeframes and response types by state
  • Employer linkage establishment
  • Monitoring and notification timing
  • Pause/resume monitoring behavior
  • Renewal handling approaches

Getting Started

Prerequisites

Before submitting WWC validations, ensure:

  1. Active organization account - Your organization must be active and in good standing
  2. Verified user status - Your API user must have completed email verification
  3. Constituents created (optional) - If linking to existing constituents, they must exist in your organization first

Universal Payload Structure

This endpoint uses a single, standardized payload structure for all WWC types. Simply change the type field to target different states - the rest of the structure remains consistent:

{
"type": "vicwwc|nswwwc|qldblue|qldblueex|sawwc|wawwc|taswwc|ntwwc|actwwc",
"identifier": "WWC_CARD_NUMBER",
"first_name": "First",
"middle_name": "Middle (optional)",
"surname": "Last",
"birth_date": "YYYY-MM-DD",
"alternate_name": "Previous Name (optional)",
"expiry": "YYYY-MM-DD (optional, required for QLD)",
"constituent": {
"id": 123
}
}

Field Descriptions

FieldTypeDescriptionRequired StatesOptional States
typestringCheck type code (see table below)All states-
identifierstringWWC card or application numberAll states-
first_namestringFirst/given nameAll states-
middle_namestringMiddle name(s)-All states
surnamestringSurname/family nameAll states-
birth_datestring (YYYY-MM-DD)Date of birthNSW, SAVIC, QLD, WA, TAS, NT, ACT
expirystring (YYYY-MM-DD)Expiry date (must be future)QLD (both types)VIC, WA (optional)
alternate_namestringMaiden/previous name-VIC, QLD, WA
constituent.idintegerLink to existing constituent-All states (recommended)

Supported Check Types

Each state has a specific type code to use in the payload:

State/TerritoryType Codebirth_dateAge CheckSpecial Notes
VictoriavicwwcOptionalNoneSupports alternate_name
New South WalesnswwwcRequired18+ (3mo grace)Auto-detects APP numbers
QueenslandqldblueOptionalNoneRequires expiry (future date)
Queensland ExemptionqldblueexOptionalNoneRequires expiry for exemptions
South AustraliasawwcRequired10+-
Western AustraliawawwcOptionalNoneSupports alternate_name, expiry
TasmaniataswwcOptionalNone-
Northern TerritoryntwwcOptionalNone-
ACTactwwcOptionalNone-

Tracking Requests

Correlation ID

When you submit a scan request, the API returns a correlation_id:

{
"correlation_id": "550e8400-e29b-41d4-a716-446655440000"
}

Important: The correlation_id does not persist from the initial request to the webhook response. You cannot rely on it to match webhook results back to your original requests.

Matching Webhook Results

To match webhook results back to your original requests, use the WWC card number (identifier) and constituent information:

Your tracking approach should be:

  1. Store the identifier (WWC card number) and constituent.id with your internal records when submitting a scan
  2. When you receive a webhook, match it using content.current.identifier and content.constituent.id
  3. Use content.current.id (the accreditation ID) for long-term references

Example tracking pattern:

// When submitting scan
await database.savePendingScan({
wwc_identifier: '1076131A',
state: 'VIC',
constituent_id: 113767,
status: 'pending',
submitted_at: new Date()
});

// When receiving webhook
async function handleWebhook(webhookData) {
const identifier = webhookData.content.current.identifier;
const constituentId = webhookData.content.constituent?.id;

// Find your record by the WWC identifier and constituent
const scan = await database.findByIdentifierAndConstituent(
identifier,
constituentId
);

// Update with results
await database.updateScan(scan.id, {
accreditation_id: webhookData.content.current.id,
status: webhookData.content.current.status,
registry_response: webhookData.content.current.registry_response
});
}

---

## Identifier Formats

Each state has specific format requirements for WWC card numbers and application numbers:

### Victoria (`type: "vicwwc"`)
- **Format:** 7 digits + 1 letter (e.g., `1076131A`)
- **Example:** `1076131A`, `2345678B`

### New South Wales (`type: "nswwwc"`)
- **Card Number Format:** `WWC` + 7 digits + 1 letter (e.g., `WWC0157654E`)
- **Application Number Format:** `APP` + 7 digits (e.g., `APP1234567`)
- **Auto-detection:** The API automatically detects whether you're submitting a card number or application number
- **Example:** `WWC0157654E` (card), `APP1234567` (application)

### Queensland (`type: "qldblue"` or `"qldblueex"`)
- **Standard Blue Card:** Typically numeric with optional `/` separator (e.g., `123456/1`), use `type: "qldblue"`
- **Exemption Card:** May include prefix `EX` (e.g., `EX123456`), use `type: "qldblueex"`
- **Example:** `123456/1` (standard), `EX123456` (exemption)

### South Australia (`type: "sawwc"`)
- **Format:** 8 digits
- **Example:** `12345678`

### Western Australia (`type: "wawwc"`)
- **Format:** `WWC` prefix + digits (e.g., `WWC987654321`)
- **Example:** `WWC987654321`

### Tasmania (`type: "taswwc"`)
- **Format:** State-specific identifier
- **Example:** `TAS123456`

### Northern Territory (`type: "ntwwc"`)
- **Format:** State-specific identifier
- **Example:** `NT987654`

### Australian Capital Territory (`type: "actwwc"`)
- **Format:** State-specific identifier
- **Example:** `ACT111222`

**Note:** While we provide common formats above, the API performs server-side validation. If you receive an identifier format error, verify the number directly with the issuing state authority.

---

## Quick Start Examples

### Victoria WWC

```bash
curl -X POST https://app.weareoho.com/api/scan \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "vicwwc",
"identifier": "1076131A",
"first_name": "Cameron",
"middle_name": "James",
"surname": "Schafer",
"alternate_name": "Cameron Smith",
"constituent": {
"id": 113767
}
}'

Success Response:

{
"correlation_id": "550e8400-e29b-41d4-a716-446655440000"
}

New South Wales WWC

Standard card number:

{
"type": "nswwwc",
"identifier": "WWC0157654E",
"first_name": "Jane",
"middle_name": "Mary",
"surname": "Doe",
"birth_date": "1985-03-15",
"constituent": {
"id": 113767
}
}

Application number (auto-detected):

{
"type": "nswwwc",
"identifier": "APP1234567",
"first_name": "John",
"middle_name": "Paul",
"surname": "Smith",
"birth_date": "1990-06-20",
"constituent": {
"id": 113768
}
}

Important: NSW requires birth_date and validates age is 18+ with a 3-month grace period (accepts applicants who will turn 18 within 3 months)


Queensland Blue Card

Standard Blue Card:

{
"type": "qldblue",
"identifier": "123456/1",
"first_name": "Michael",
"middle_name": "Andrew",
"surname": "Williams",
"alternate_name": "Mike Williams",
"expiry": "2026-12-31",
"constituent": {
"id": 113800
}
}

Blue Card Exemption:

{
"type": "qldblueex",
"identifier": "EX123456",
"first_name": "Sarah",
"middle_name": "Jane",
"surname": "Thompson",
"expiry": "2025-06-30",
"constituent": {
"id": 113801
}
}

Important:

  • QLD Blue Card requires expiry field (must be a future date)
  • Use type: "qldblue" for regular cards or type: "qldblueex" for exemptions
  • birth_date is optional but recommended

South Australia WWC

{
"type": "sawwc",
"identifier": "12345678",
"first_name": "David",
"middle_name": "Wei",
"surname": "Lee",
"birth_date": "1988-11-30",
"constituent": {
"id": 113769
}
}

Important:

  • SA requires birth_date and validates age is 10+
  • SA WWCC requires a middle name to be included in the full_name field (provided as first_name, middle_name, surname)

Western Australia WWC

{
"type": "wawwc",
"identifier": "WWC987654321",
"first_name": "Michael",
"middle_name": "Thomas",
"surname": "Brown",
"alternate_name": "Mike Brown",
"expiry": "2027-08-22",
"constituent": {
"id": 113770
}
}

Tasmania WWC

{
"type": "taswwc",
"identifier": "TAS123456",
"first_name": "Emma",
"middle_name": "Rose",
"surname": "Wilson",
"constituent": {
"id": 113771
}
}

Northern Territory WWC

{
"type": "ntwwc",
"identifier": "NT987654",
"first_name": "Robert",
"middle_name": "Li",
"surname": "Chen",
"constituent": {
"id": 113772
}
}

Australian Capital Territory WWC

{
"type": "actwwc",
"identifier": "ACT111222",
"first_name": "Sarah",
"middle_name": "Elizabeth",
"surname": "Johnson",
"constituent": {
"id": 113773
}
}

Linking to Existing Constituents

The API supports three workflows for managing WWC accreditations:

When you want to associate the WWC check with a person already in your system:

{
"type": "vicwwc",
"identifier": "1076131A",
"first_name": "Cameron",
"surname": "Schafer",
"birth_date": "1985-06-15",
"constituent": {
"id": 113767
}
}

Behavior:

  • ✅ Links accreditation to constituent ID 113767
  • ✅ Accreditation appears in constituent's profile
  • ✅ Auto-updates constituent with birth_date, mobile_number, email if those fields are null
  • ❌ Returns 400 error if constituent ID doesn't exist in your organization

When to use:

  • You have a constituent database and want to track WWC checks against people
  • You need to see all accreditations for a specific person
  • You want centralized compliance tracking

Scenario 2: Standalone Accreditation (No Constituent)

When you only want to validate credentials without linking to a person record:

{
"type": "vicwwc",
"identifier": "1076131A",
"first_name": "Cameron",
"surname": "Schafer",
"birth_date": "1985-06-15"
}

Behavior:

  • ✅ Creates standalone accreditation record
  • ✅ Validates credentials against registry
  • ✅ Stores result in your organization
  • ⚠️ Not linked to any constituent profile
  • ⚠️ Can be linked later via the UI or API

When to use:

  • Quick one-off validations
  • You don't maintain a constituent database
  • Validating external contractors or visitors
  • Testing/development

Scenario 3: Invalid Constituent ID (Error)

When you provide a constituent ID that doesn't exist:

{
"type": "vicwwc",
"identifier": "1076131A",
"first_name": "Cameron",
"surname": "Schafer",
"constituent": {
"id": 999999
}
}

Response (400 Bad Request):

{
"status": 400,
"message": "Validation error",
"errors": {
"constituent": {
"id": ["Constituent doesn't exist in your organization"]
}
}
}

How to avoid:

  1. Create the constituent first using POST /api/constituents
  2. Then submit the scan with the returned constituent ID
  3. Or omit constituent entirely for standalone accreditation

Webhook Configuration

Since the /api/scan endpoint processes requests asynchronously, results are delivered to your webhook endpoint when validation completes.

Webhook Setup & Security

For detailed instructions on:

  • Setting up webhook endpoints
  • Configuring webhook URLs
  • Verifying webhook signatures
  • Security best practices
  • Retry behavior and error handling

See the Webhook Integration Guide.

Webhook Payload Structure

When a scan completes, we POST the following JSON to your webhook:

{
"event": "accreditation_validation",
"correlation_id": "a8f5d2e1-3c4b-4d5e-8f9a-1b2c3d4e5f6a",
"message_id": 12345,
"content": {
"notification_type": "accreditation-result",
"org_id": 123,
"previous": null,
"current": {
"id": 5354,
"identifier": "1076131A",
"type": "vicwwc",
"status": "active",
"status_color": "green",
"status_flags": {
"current": true,
"may_engage": true,
"expired": false,
"expiring": false
},
"registry_response": {
"may_engage": true,
"response": ["Current", "May Engage"],
"oho_status": "active",
"card_type": "employee_wwc"
}
},
"constituent": {
"id": 113767,
"first_name": "Cameron",
"surname": "Schafer",
"email": "cameron@example.com",
"organization": {
"id": 123,
"name": "Organization Name",
"abn": "12345678901",
"is_active": true
}
},
"entity_type_id": 3,
"event_type_id": 2,
"changed_fields": null
}
}

Key webhook fields:

  • correlation_id - Matches the UUID from your scan request
  • content.current - Contains the complete accreditation details
  • content.previous - Previous state (null for new checks, populated for updates)
  • content.constituent - Details about the person checked

Status Values

The content.current.status field indicates the check result:

StatusDescription
activeValid and current clearance
inactiveClearance expired or revoked
suspendedClearance temporarily suspended
cancelledClearance cancelled

The content.current.status_flags object provides detailed state information:

FlagDescription
currentWhether the clearance is currently valid
may_engageWhether the person is authorized to work with children
expiredWhether the clearance has expired
expiringWhether the clearance is expiring soon

Error Webhook Example

When validation fails, the webhook contains error details:

{
"event": "accreditation_validation",
"correlation_id": "b9e8d5f2-4c3a-5d6e-9f0a-2b3c4d5e6f7a",
"message_id": 12346,
"content": {
"notification_type": "accreditation-result",
"org_id": 123,
"previous": null,
"current": {
"id": null,
"identifier": "INVALID123",
"type": "nswwwc",
"status": "error",
"error": {
"message": "Invalid WWC number or details do not match",
"code": "VALIDATION_FAILED"
}
},
"constituent": {
"id": 113768,
"first_name": "Jane",
"surname": "Smith"
},
"entity_type_id": 3,
"event_type_id": 2,
"changed_fields": null
}
}

Registry Response Structure

The registry_response object in webhook payloads contains state-specific validation results. Here's the common structure:

{
"may_engage": true,
"response": ["Current", "May Engage"],
"oho_status": "active",
"card_type": "employee_wwc",
"expiry_date": "2027-06-15"
}

Common Fields:

  • may_engage (boolean) - Whether the person is cleared to work with children
  • response (array) - Status indicators from the registry
  • oho_status (string) - Normalized status: active, inactive, expired, suspended, cancelled
  • card_type (string) - Type of WWC card (state-specific)
  • expiry_date (string) - Expiry date if available

Common Status Values

The oho_status field provides a normalized status across all states:

StatusDescriptionmay_engage
activeCurrent and valid, may work with childrentrue
inactiveNot currently active, do not engagefalse
expiredCard has expiredfalse
suspendedTemporarily suspendedfalse
cancelledPermanently cancelledfalse
pendingApplication pending (APP numbers)false
interimInterim clearance granted (some states)true

Best practice: Always check both may_engage and oho_status fields to determine if someone is cleared to work with children.


Error Responses

Age Validation Error - NSW (400)

{
"status": 400,
"message": "Validation error",
"errors": {
"birth_date": ["Age should be 18+, given - 2010-01-01"]
}
}

Age Validation Error - SA (400)

{
"status": 400,
"message": "Validation error",
"errors": {
"birth_date": ["Age should be 10+, given - 2015-01-01"]
}
}

Expired Date - QLD (400)

{
"status": 400,
"message": "Validation error",
"errors": {
"expiry": ["Date is in the past"]
}
}

Missing Required Field - QLD (400)

{
"status": 400,
"message": "Validation error",
"errors": {
"expiry": ["Missing data for required field."]
}
}

Invalid Constituent (400)

{
"status": 400,
"message": "Validation error",
"errors": {
"constituent": {
"id": ["Constituent doesn't exist in your organization"]
}
}
}

Authentication Error (401)

{
"status": 401,
"message": "You are not authorized to view this resource",
"field": "authentication"
}

Service Unavailable (503)

{
"status": 503,
"message": "The target resource is currently unavailable"
}

Best Practices

1. Use the Universal Payload Structure

For maximum compatibility and consistency, always include all applicable fields:

{
"type": "OHO_ACCRED_TYPE_CODE",
"identifier": "CARD_NUMBER",
"first_name": "First",
"middle_name": "Middle",
"surname": "Last",
"birth_date": "YYYY-MM-DD",
"alternate_name": "Previous Name",
"expiry": "YYYY-MM-DD",
"constituent": {
"id": 123
},
"correlation_id": "your-unique-id"
}

Even if some fields are optional for certain states, using the same structure everywhere:

  • Ensures your payload works across all states
  • Simplifies your codebase (one payload template)
  • Provides better tracking and data consistency
  • Future-proofs your integration

2. State-Specific Requirements

Always include for these states:

StateRequired Fields
NSWbirth_date (18+ with 3mo grace)
SAbirth_date (10+)
QLDexpiry (future date)
QLD Exemptionexpiry (future date)

3. Prevent Duplicate Scans

Use the WWC card number (identifier) and constituent ID to track and prevent duplicate scans:

// Check if already scanned before submitting
const existing = await database.findByIdentifierAndConstituent(
'1076131A',
113767
);
if (existing && existing.scanned_recently) {
// Skip scan or use cached result
return existing;
}

// Submit new scan
await submitWWCVerification({
type: 'vicwwc',
identifier: '1076131A',
first_name: 'Cameron',
surname: 'Schafer',
constituent: { id: 113767 }
});

4. Handle Webhooks Reliably

  • Return 200 OK quickly (within 10 seconds)
  • Process webhook data asynchronously in your application
  • Match webhooks using identifier and constituent.id (not correlation_id)
  • Implement webhook signature verification
  • Store the accreditation.id for long-term references

Complete Integration Example

Step 1: Submit Scan

curl -X POST https://app.weareoho.com/api/scan \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "vicwwc",
"identifier": "1076131A",
"first_name": "Cameron",
"middle_name": "James",
"surname": "Schafer",
"birth_date": "1985-06-15",
"alternate_name": "Cameron Smith",
"constituent": {
"id": 113767
}
}'

Step 2: Receive Response

{
"correlation_id": "550e8400-e29b-41d4-a716-446655440000"
}

Step 3: Store Request Details

// Store the identifier and constituent ID for matching webhooks
await database.createScanRequest({
identifier: '1076131A',
wwc_type: 'vicwwc',
constituent_id: 113767,
status: 'pending',
submitted_at: new Date()
});

Step 4: Receive Webhook (Later)

{
"event": "accreditation_validation",
"correlation_id": "a8f5d2e1-3c4b-4d5e-8f9a-1b2c3d4e5f6a",
"message_id": 12345,
"content": {
"notification_type": "accreditation-result",
"org_id": 123,
"previous": null,
"current": {
"id": 5354,
"identifier": "1076131A",
"type": "vicwwc",
"status": "active",
"status_flags": {
"current": true,
"may_engage": true,
"expired": false,
"expiring": false
},
"registry_response": {
"may_engage": true,
"response": ["Current", "May Engage"],
"oho_status": "active",
"card_type": "employee_wwc"
}
},
"constituent": {
"id": 113767,
"first_name": "Cameron",
"surname": "Schafer",
"email": "cameron@example.com"
}
}
}

Note: The correlation_id in the webhook may differ from the one returned in Step 2. Use the identifier and constituent.id to match results.

Step 5: Process Webhook

async function handleWebhook(req, res) {
// 1. Verify signature
const signature = req.headers['x-hub-signature'];
if (!verifyWebhook(req.body, signature, process.env.OHO_SECRET)) {
return res.status(403).send('Invalid signature');
}

const payload = JSON.parse(req.body);

// 2. Match to your records using identifier and constituent
const identifier = payload.content.current.identifier;
const constituentId = payload.content.constituent?.id;

const scanRequest = await database.findByIdentifierAndConstituent(
identifier,
constituentId
);

// 3. Update your records
await database.updateScanRequest(scanRequest.id, {
status: req.body.status,
accreditation_id: req.body.accreditation?.id,
may_engage: req.body.accreditation?.registry_response?.may_engage
});

// 4. Respond quickly
res.status(200).send('OK');

// 5. Process asynchronously (after response sent)
processResult(req.body);
}

FAQ

Q: Do I need to provide all fields in the payload?

A: Required fields vary by state:

  • Always required: type, identifier, first_name, surname
  • NSW & SA: birth_date is required
  • QLD: expiry is required (must be future date)
  • All others: Optional (middle_name, alternate_name, expiry, constituent.id)

However, using a consistent payload structure for all requests simplifies your codebase and ensures compatibility.

Q: What's the difference between qldblue and qldblueex?

A: Queensland has two check types:

  • qldblue - Standard Blue Card (regular checks)
  • qldblueex - Blue Card exemption Both require the expiry field.

Q: What if I submit the same scan twice?

A: Each request creates a new scan. To prevent duplicates, check your database for existing scans of the same WWC number and constituent before submitting. Track scans using the combination of identifier (WWC card number) and constituent.id rather than relying on correlation_id.

Note: For persistent tracking after webhook delivery, use the returned accreditation.id from the webhook response.

Q: What if the constituent doesn't exist?

A: You'll get a 400 error. Either:

  1. Create the constituent first using POST /api/constituents
  2. Or omit the constituent field to create a standalone accreditation

Q: Can I get synchronous responses?

A: The async /api/scan endpoint is recommended for production. Contact support if you need information about synchronous scanning options for testing/development.


Troubleshooting

Common Issues and Solutions

1. 401 Unauthorized Error

Problem: {"status": 401, "message": "You are not authorized to view this resource"}

Solutions:

  • ✅ Verify your API token is correct and hasn't expired
  • ✅ Check the Authorization header format: Bearer YOUR_TOKEN
  • ✅ Ensure your user account is verified (check email)
  • ✅ Confirm your organization is active and in good standing

2. 400 Validation Error - Age Check Failed

Problem (NSW): {"errors": {"birth_date": ["Age should be 18+, given - 2010-01-01"]}}

Solutions:

  • ✅ Verify the person is at least 18 years old (or will be within 3 months for NSW)
  • ✅ Check birth_date format is correct: YYYY-MM-DD
  • ✅ For SA, verify age is 10+

3. 400 Validation Error - Missing Required Field

Problem (QLD): {"errors": {"expiry": ["Missing data for required field."]}}

Solutions:

  • ✅ QLD Blue Cards require expiry field
  • ✅ Expiry must be a future date
  • ✅ Format: YYYY-MM-DD

4. 400 Constituent Not Found

Problem: {"errors": {"constituent": {"id": ["Constituent doesn't exist in your organization"]}}}

Solutions:

  • ✅ Create the constituent first: POST /api/constituents
  • ✅ Verify you're using the correct constituent ID
  • ✅ Or omit constituent field entirely for standalone accreditation

5. Webhook Not Receiving Results

Problem: Scan submitted successfully but no webhook callback received

Solutions:

  • ✅ Verify webhook URL is configured in Settings → Webhooks
  • ✅ Ensure webhook endpoint is publicly accessible via HTTPS
  • ✅ Check webhook endpoint returns 200 OK within 10 seconds
  • ✅ Verify no firewall blocking incoming requests
  • ✅ Look for failed webhooks in your dashboard

Quick Reference

Endpoint Summary

Endpoint: POST /api/scan

Content-Type: application/json

Authentication: Authorization: Bearer YOUR_TOKEN

Type Codes

StateType Codebirth_dateAgeSpecial Requirements
VictoriavicwwcOptionalNone-
NSWnswwwcRequired18+Auto-detects APP numbers
QueenslandqldblueOptionalNoneexpiry required (future)
QLD ExemptionqldblueexOptionalNoneexpiry required (future)
South AustraliasawwcRequired10+-
Western AustraliawawwcOptionalNone-
TasmaniataswwcOptionalNone-
Northern TerritoryntwwcOptionalNone-
ACTactwwcOptionalNone-

Field Requirements

Always required:

  • type - Check type code (vicwwc, nswwwc, qldblue, etc.)
  • identifier - WWC card/application number
  • first_name - First/given name
  • surname - Surname/family name

State-specific required:

  • NSW & SA: birth_date
  • QLD: expiry (must be future date)

Optional for all states:

  • middle_name
  • alternate_name (supported: VIC, QLD, WA)
  • birth_date (except NSW & SA)
  • expiry (except QLD)
  • constituent.id

Common HTTP Status Codes

CodeMeaningCommon Cause
200SuccessRequest queued successfully
400Bad RequestValidation error (missing/invalid field)
401UnauthorizedInvalid/missing API token
429Too Many RequestsRate limit exceeded
503Service UnavailableRegistry temporarily unavailable

Webhook Status Values

StatusDescriptionAction Required
completedValidation successfulUse result
errorValidation failedCheck error message, verify details
timeoutRegistry timeout (>30s)Retry scan
invalidInvalid credentialsVerify card number and details


Document Version

Version: 2.1 Last Updated: 2025-11-13 Endpoint: POST /api/scan (Universal with type field) Status: Production Ready