Developer guide

Australian sanctions API in Ruby: DFAT screening jobs

Run Australian sanctions API checks in a Ruby background job. Use DFAT source IDs and save alias evidence with the customer’s review.

250 free live screenings. One lifetime allowance. No credit card required.
On this page

Run Australian screening in a Ruby job

A customer renewal or corrected legal identity can create a new screening operation under your policy. Persist the event reason, subject and selected Australian coverage before enqueuing work. The worker should load that record instead of reconstructing a potentially changed customer from a display name.

When a job retries after a transport failure, preserve the original operation identity. A customer correction is a separate event with a new payload and key. Keeping these cases distinct makes it possible to explain whether a later result reflects recovery or a genuinely new comparison.

Prepare the synthetic exercise

Give an invented customer renewal and a corrected legal name different saved event references. The Ruby worker should load the event’s stored subject, not reconstruct it from the latest display name. This tests whether later corrections can accidentally alter an earlier queued operation.

Ruby setup and request files
RequirementValue or action
RuntimeUse Ruby 3.1 or later with its standard JSON, Net::HTTP, URI, and OpenSSL libraries. The script is intended for a backend or trusted CLI and needs no provider SDK.
Client fileSave the client as screen.rb
Screening endpointPOST /api/v1/screenings
SANCTIONSKIT_API_KEYSandbox key; screenings:write and results:read scopes
SCREENING_OPERATION_IDPersist one operation ID; reuse only with the identical request body
request.jsonMira Calder: invented subject; sandbox@1: synthetic records
request.json: synthetic sandbox request
{
  "subject": {
    "name": "Mira Calder",
    "entityType": "person",
    "birthDate": "1984"
  },
  "package": "sandbox@1",
  "retention": "standard"
}

Implement the Ruby request boundary

Use Net::HTTP within a job that owns the original operation key and body. A retry after a network failure should recover that event. A renewal or corrected identity is a different event and therefore requires a new operation, even if the same Ruby job class handles both.

Ruby: authenticated screening client
# Ruby 3.1+. Standard library only. Backend or trusted CLI.
require 'json'
require 'net/http'
require 'uri'
require 'openssl'
begin
  key = ENV.fetch('SANCTIONSKIT_API_KEY')
  operation = ENV.fetch('SCREENING_OPERATION_ID')
  raise 'Operation ID must not be empty.' if operation.empty?
  raw = File.binread(ARGV[0] || 'request.json')
  raise 'Request file exceeds 64 KiB.' if raw.bytesize > 65_536
  body = JSON.parse(raw)
  unless body.is_a?(Hash) && body['subject'] && (body.key?('sources') ^ body.key?('package'))
    raise 'Supply a subject and exactly one of sources or package.'
  end
  uri = URI('https://www.sanctionskit.com/api/v1/screenings')
  request = Net::HTTP::Post.new(uri)
  request['Authorization'] = "Bearer #{key}"
  request['Content-Type'] = 'application/json'
  request['Idempotency-Key'] = operation
  request.body = JSON.generate(body)
  payload = +''
  status = 0
  Net::HTTP.start(uri.host, uri.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER,
                  open_timeout: 10, read_timeout: 25, write_timeout: 25) do |http|
    http.max_retries = 0
    http.request(request) do |response|
      status = response.code.to_i
      response.read_body do |chunk|
        raise 'Response size limit exceeded.' if payload.bytesize + chunk.bytesize > 8 * 1024 * 1024
        payload << chunk
      end
    end
  end
  # Net::HTTP does not automatically follow redirects.
  envelope = JSON.parse(payload)
  raise "Screening incomplete: HTTP #{status}." unless (200...300).cover?(status)
  data = envelope.is_a?(Hash) ? envelope['data'] : nil
  unless data.is_a?(Hash) && data['id'].is_a?(String) && !data['id'].empty? &&
         %w[potential_match no_match].include?(data['status']) && data['matches'].is_a?(Array)
    raise 'Incomplete response: unexpected screening shape.'
  end
  count = data['matches'].length
  if (data['status'] == 'no_match' && count != 0) || (data['status'] == 'potential_match' && count == 0)
    raise 'Incomplete response: inconsistent screening shape.'
  end
  puts JSON.generate(id: data['id'], status: data['status'], candidateCount: count)
rescue StandardError => error
  warn "Screening did not complete: #{error.class}. Check the operation before retrying."
  exit 1
end

Run the client

Run the sandbox request
ruby screen.rb request.json

Confirm Australian sanctions scope before production

Choose au-consolidated for the DFAT list and retain that selection with each renewal event. An unavailable or stale Australian source must leave the event incomplete; it cannot be replaced with a no-match outcome just to clear the queue.

Production source-discovery contract
CheckRequired evidence
GET /api/v1/sourcesProduction key with sources:read; response data array
idau-consolidated
availability / freshavailable / true
capabilitiesContains the requested subject.entityType
currentVersionActive version; retrieved_at and last_checked_at are not publication dates
lastImportMay describe an import that is not the active version
Missing or ineligible sourceInspect disabledReason; required coverage stays incomplete
Displayed clientAdd these discovery checks before its production call
Read source discovery with your production key
curl --fail-with-body --max-time 25 --header "Authorization: Bearer $SANCTIONSKIT_API_KEY" "https://www.sanctionskit.com/api/v1/sources"

Select au-consolidated in the production request

Explicit change from the sandbox exercise
SettingProduction request
KeySeparate production credential with screenings:write
Coveragesources: ["au-consolidated"]; omit package
Operation IDNew ID for the changed body and environment
UsageProduction access and screening allowance apply
SubjectOnly lawfully held, known identifying facts; no invented date precision
request.json: explicit au-consolidated selection
{
  "subject": {
    "name": "Mira Calder",
    "entityType": "person",
    "birthDate": "1984"
  },
  "sources": [
    "au-consolidated"
  ],
  "retention": "standard"
}

Interpret Australian sanctions evidence in this workflow

Keep data.id, data.coverage and the renewal reason together. Reviewers should be able to tell whether a later screening reflects new customer details or recovery of a failed request. Preserve the original aliases and source record references with each completed result.

Australian sanctions candidate fields to retain
Fields in data.matches[]Review use
record.id and record.namesRetain the DFAT source reference with the primary name and aliases; one listed identity may have several names.
record.designationsDisplay the available designation, program, legal-reference and effective-date context.
record.birthDates, identifiers and addressesCompare the known identity details and retain uncertain dates at the precision supplied.
  • data.id; data.coverage; data.versions; supplied disclaimer
  • data.matches[]: record, assessment, evidence, conflicts
  • GET /api/v1/results/{id}: results:read scope
  • Retained evidence and case review

Verify the application behavior

Recovery rules for the same saved operation
ConditionNext action
401 / 403Correct credentials or scopes before retrying
coverage_unavailable / stale_coverageKeep required coverage incomplete; no silent source substitution
Timeout after submissionRecover with the original Idempotency-Key and identical body
409Investigate an operation-key conflict
429 / 503Follow the specific error and Retry-After; an allowance cap may require a plan or usage change
Contract and safe diagnostic references
Operational reference
ReferenceUse
error.code / error.requestIdSafe recovery diagnostics; never log the submitted subject, key or full candidate response
potential_match / no_matchCompleted comparison outcomes; neither is an automatic business approval
  • Change the customer after enqueueing and confirm the original operation body stays unchanged.
  • Give a corrected identity a new operation key.
  • Mock stale_coverage and keep the renewal event incomplete.

Sources and references

Frequently asked questions

Should a Ruby DFAT job load the latest customer name every time it retries?

No. Load the subject saved with that operation. Reconstructing it from a changed customer record can turn a retry into a different request while reusing the old key, making recovery ambiguous.

How does a Ruby service distinguish Australian renewal checks from retries?

Persist the event reason and operation identity. A renewal or corrected subject creates new work; a transport retry recovers the original request. The same worker class can handle both without conflating them.

What should a Ruby job do when the Australian source is stale?

Leave the screening incomplete and check the source freshness error. Do not turn stale_coverage into no_match. Keep the original operation and required source so it can be recovered when freshness is restored.

Can a stale DFAT source be treated as a completed Ruby job?

You may record a durable failure state, but the screening itself remains incomplete. Do not label it no_match or advance the customer merely because the queue framework finished executing the job.