Skip to content

ProAssign API

Base path through the gateway: /api/identification/v1/proassigns. Every call needs a signed-in profile (bearer); registering and the owner suggestion additionally require the acting profile to hold a professional specialization (veterinarian, vet tech, practice, shelter/rescue, breeder, groomer, trainer, carer, responder) — otherwise identification.professional_required (403). Responses use the platform envelope { data, resultCode }. This page is the reference. The service’s own OpenAPI document is for UPC platform staff only.

A registration parks the identifier in status PRO_REGISTERED: recoverable at once (scans resolve to the registering professional), owned by nobody. Ownership arrives one of three ways and always ends as a normal claimed identifier (OwnershipGrant with reason PRO_ASSIGN):

MethodTrigger
KNOWN_OWNERyou supplied ownerProfileId at registration and that owner approved it (POST /proassigns/{id}/approve); with animalId the identifier is bound to that animal on approval. Since 2026-09-24 nothing is granted at registration
CLAIM_CODEthe owner posts the printed identifier + the one-time code you were returned once
CONTACT_MATCHthe owner signed up with a verified email / phone equal to what you captured; awaiting-me lists it, claim-by-contact claims it

expiresInDays (default 365, max 1095) bounds the code only. Recovery resolution never stops.

POST /proassigns → 201 ProAssignResultDto { proAssign, identifier, claimCode? }

{
"kind": "MICROCHIP",
"rawCode": "985 141 000 123 456",
"referenceNumber": "CLINIC-4471",
"ownerName": "Jane Doe",
"ownerPhone": "+1 555 010 2000",
"ownerEmail": "jane@example.com",
"ownerCountryCode": "CA",
"isRecoveryContactable": true,
"callName": "Bella",
"speciesId": "…",
"breedId": "…",
"animalSexCode": "F",
"appliedAtUtc": "2026-09-08T14:00:00Z",
"implantedAtName": "Happy Paws Clinic",
"expiresInDays": 365
}
  • kind: MICROCHIP (15-digit ISO or 9–10-digit legacy, else identification.invalid_identifier_format), VISUAL_TAG / RFID_TAG / NFC_TAG / QR_TAG, TATTOO, PASSPORT_NUMBER. A tag code pre-staged under another tag family is matched by code.
  • Owner: either ownerProfileId (+ optional ownerAccountId; resolved from the profile when omitted, else identification.owner_account_unresolved), which addresses the registration to that owner to approve or decline (proAssign.awaitingOwnerApproval: true, identifier still PRO_REGISTERED), or both ownerPhone and ownerEmail (identification.contact_required).
  • Animal: either animalId (requires ownerProfileId, and must be that owner’s animal: identification.unauthorized 403 when it is someone else’s, 404 when unknown, 503 when the animal service cannot answer), or callName + speciesId (required) with the optional localName, registeredName, breedId, animalSexCode, colorText, dateOfBirth, descriptionText.
  • Whether the number is a United Pet Club chip or tag is decided by UPC from its own stock, never by the request: an isUpcIssued you send is ignored. When that check cannot be made the call answers identification.dependency_unavailable (503); retry it.
  • claimCode is present only when no owner profile was named, and is never returned again. Conflicts: identification.duplicate_identity (already owned), identification.pro_assign_exists (open registration exists).
  • POST /proassigns/{id}/approve { animalId?, isPrimary?, skipAnimal? } — the owner you named takes the identifier (KNOWN_OWNER) and it is bound to the animal you named, to another of their own animals (animalId), or to none (skipAnimal). Only that owner (or platform staff) may call it (403 otherwise); an animal that is not theirs is refused.
  • POST /proassigns/{id}/decline { reason? } — the registration stays with you, unclaimed and recoverable to you; declinedAtUtc and declineReason show on it. Void it or re-issue a claim code for the client.

A declined, claimed or voided registration answers 409. While a registration waits for the owner you named, its claim code and a contact match do not take it.

  • POST /proassigns/claim { claimCode, code, kind?, ownerProfileId?, ownerAccountId?, animalId?, isPrimary? } — by printed identifier.
  • POST /proassigns/{id}/claim — same body, by registration id.
  • GET /proassigns/awaiting-me → ProAssignAwaitingDto[] { proAssign, matchedBy, registeredByDisplayName, registeredByHandle } — matchedBy is NAMED for a registration addressed to the acting profile (approve or decline it), else EMAIL / PHONE.
  • POST /proassigns/{id}/claim-by-contact { ownerProfileId?, ownerAccountId?, animalId?, isPrimary? } — re-verified server-side; 403 when no verified contact matches.

ownerProfileId defaults to the acting profile and must be it (another profile is 403), ownerAccountId defaults to the token’s account. Wrong code → identification.invalid_credential (400); five wrong codes lock the registration; past the window → identification.claim_expired (409). With animalId — which must be the claimer’s own animal — the identifier is bound in the same call and Identification.IdentifierAssigned.v1 is emitted (the Animal service mirrors it onto the animal’s identification rows).

  • GET /proassigns/mine?status=&includeClosed=&skip=&take= — your registrations (as registrant or as the registering organisation).
  • GET /proassigns/{id}; GET /proassigns/by-code/{code}?kind=&namespace= — client contact is redacted unless you registered it, your organisation did, you claimed it, or you are staff (contactRedacted: true).
  • POST /proassigns/{id}/reissue-code → new claimCode, unlocked, window re-opened.
  • POST /proassigns/{id}/void { reason? } → identifier returns to UNCLAIMED.
  • POST /proassigns/owner-suggestions { email?, phone? } → { found, profileId, handle, displayName, matchedBy } — whether a member has verified that contact. Confirm with your client before registering against the suggested profile.
  • Breeding: GET /api/breeding/v1/litters/lookup?code=&ownerProfileId= (bearer) — a litter by its code or a breeder’s newest litters, with offspring animal ids, so a professional can pick the right animal from a litter.
  • Animal: GET /api/animal/v1/identifiers/{value}/resolve answers ANIMAL / NONE for the registry’s own identification rows; professional pre-registrations are answered by /proassigns/by-code/{code} above.
  • Public lookup (POST /api/identification/v1/lookup) resolves an unclaimed professional registration as a MATCH with isProfessionallyRegistered: true; the finder relay reaches the registering practice.