Registration/Verification/Identification
Pet fingerprint registration, verification (1:1), and identification (1:N) API guide.
Overview
Petnow API provides three core features:
| Feature | Description | Use Case |
|---|---|---|
| Registration | Add fingerprints to pet | Register new pet |
| Verification | 1:1 matching | Confirm "Is this the right pet?" |
| Identification | 1:N matching | Find "Who is this pet?" |
Add Fingerprints (Registration)
Add fingerprints from a capture session to a pet.
Endpoint: POST /v2/pets/{petId}:addFingerprints
Complete Flow
Request
curl -X POST "https://api.b2b.petnow.io/v2/pets/pet-uuid-1234:addFingerprints" \
-H "x-petnow-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "session-uuid-abcd"
}'import requests
import time
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.b2b.petnow.io"
HEADERS = {"x-petnow-api-key": API_KEY}
def add_fingerprints(pet_id: str, session_id: str):
# Request fingerprint addition
response = requests.post(
f"{BASE_URL}/v2/pets/{pet_id}:addFingerprints",
headers={**HEADERS, "Content-Type": "application/json"},
json={"sessionId": session_id}
)
job_id = response.json()["data"]["jobId"]
print(f"Job started: {job_id}")
# Poll for job status
while True:
status_response = requests.get(
f"{BASE_URL}/v2/fingerprint-addition-jobs/{job_id}",
headers=HEADERS
)
result = status_response.json()["data"]
status = result["status"]
print(f"Status: {status}")
if status == "SUCCESS":
print("Fingerprints added successfully!")
return result
elif status == "FAILED":
raise Exception(f"Job failed: {result.get('error')}")
time.sleep(2) # Wait 2 seconds
# Usage example
result = add_fingerprints("pet-uuid-1234", "session-uuid-abcd")const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://api.b2b.petnow.io";
async function addFingerprints(petId, sessionId) {
const headers = { "x-petnow-api-key": API_KEY };
// Request fingerprint addition
const response = await fetch(
`${BASE_URL}/v2/pets/${petId}:addFingerprints`,
{
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ sessionId })
}
);
const jobId = (await response.json()).data.jobId;
console.log(`Job started: ${jobId}`);
// Poll for job status
while (true) {
const statusResponse = await fetch(
`${BASE_URL}/v2/fingerprint-addition-jobs/${jobId}`,
{ headers }
);
const result = (await statusResponse.json()).data;
const status = result.status;
console.log(`Status: ${status}`);
if (status === "SUCCESS") {
console.log("Fingerprints added successfully!");
return result;
} else if (status === "FAILED") {
throw new Error(`Job failed: ${result.error}`);
}
await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds
}
}
// Usage example
const result = await addFingerprints("pet-uuid-1234", "session-uuid-abcd");Response (Job Started)
{
"data": {
"jobId": "job-uuid-1234"
}
}Job Status Response
{
"data": {
"status": "SUCCESS",
"petId": "pet-uuid-1234",
"addedCount": 5
}
}Pet Verification
Verify if captured biometric data matches a specific pet (1:1 matching).
Endpoint: POST /v2/pets/{petId}:verify
Complete Flow
Request
curl -X POST "https://api.b2b.petnow.io/v2/pets/pet-uuid-1234:verify" \
-H "x-petnow-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "session-uuid-abcd"
}'import requests
import time
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.b2b.petnow.io"
HEADERS = {"x-petnow-api-key": API_KEY}
def verify_pet(pet_id: str, session_id: str):
# Request verification
response = requests.post(
f"{BASE_URL}/v2/pets/{pet_id}:verify",
headers={**HEADERS, "Content-Type": "application/json"},
json={"sessionId": session_id}
)
job_id = response.json()["data"]["jobId"]
print(f"Verification job started: {job_id}")
# Poll for job status
while True:
status_response = requests.get(
f"{BASE_URL}/v2/verification-jobs/{job_id}",
headers=HEADERS
)
result = status_response.json()["data"]
status = result["status"]
if status == "SUCCESS":
is_verified = result["isVerified"]
score = result["score"]
print(f"Verified: {is_verified}, Score: {score}")
return result
elif status == "FAILED":
raise Exception(f"Verification failed: {result.get('error')}")
time.sleep(2)
# Usage example
result = verify_pet("pet-uuid-1234", "session-uuid-abcd")
if result["isVerified"]:
print("✅ Identity confirmed!")
else:
print("❌ Does not match")const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://api.b2b.petnow.io";
async function verifyPet(petId, sessionId) {
const headers = { "x-petnow-api-key": API_KEY };
// Request verification
const response = await fetch(
`${BASE_URL}/v2/pets/${petId}:verify`,
{
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ sessionId })
}
);
const jobId = (await response.json()).data.jobId;
console.log(`Verification job started: ${jobId}`);
// Poll for job status
while (true) {
const statusResponse = await fetch(
`${BASE_URL}/v2/verification-jobs/${jobId}`,
{ headers }
);
const result = (await statusResponse.json()).data;
if (result.status === "SUCCESS") {
console.log(`Verified: ${result.isVerified}, Score: ${result.score}`);
return result;
} else if (result.status === "FAILED") {
throw new Error(`Verification failed: ${result.error}`);
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
// Usage example
const result = await verifyPet("pet-uuid-1234", "session-uuid-abcd");
if (result.isVerified) {
console.log("✅ Identity confirmed!");
} else {
console.log("❌ Does not match");
}Verification Result Response
{
"data": {
"status": "SUCCESS",
"isVerified": true,
"score": 95
}
}| Field | Type | Description |
|---|---|---|
status | string | PENDING, SUCCESS, FAILED |
isVerified | boolean | Whether verification passed |
score | number | Confidence score (0-100) |
Pet Identification
Find matching pets in the database from captured biometric data (1:N matching).
Endpoint: POST /v2/pets:identify
Complete Flow
Request
curl -X POST "https://api.b2b.petnow.io/v2/pets:identify" \
-H "x-petnow-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "session-uuid-abcd"
}'import requests
import time
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.b2b.petnow.io"
HEADERS = {"x-petnow-api-key": API_KEY}
def identify_pet(session_id: str):
# Request identification
response = requests.post(
f"{BASE_URL}/v2/pets:identify",
headers={**HEADERS, "Content-Type": "application/json"},
json={"sessionId": session_id}
)
job_id = response.json()["data"]["jobId"]
print(f"Identification job started: {job_id}")
# Poll for job status
while True:
status_response = requests.get(
f"{BASE_URL}/v2/identification-jobs/{job_id}",
headers=HEADERS
)
result = status_response.json()["data"]
status = result["status"]
if status == "SUCCESS":
pets = result.get("pets", [])
print(f"Found {len(pets)} matching pet(s)")
for pet in pets:
print(f" - {pet['id']}: score={pet['score']}")
return result
elif status == "FAILED":
raise Exception(f"Identification failed: {result.get('error')}")
time.sleep(2)
# Usage example
result = identify_pet("session-uuid-abcd")
if result["pets"]:
best_match = result["pets"][0]
print(f"Best match: {best_match['id']} (score: {best_match['score']})")
else:
print("No matching pets found")const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://api.b2b.petnow.io";
async function identifyPet(sessionId) {
const headers = { "x-petnow-api-key": API_KEY };
// Request identification
const response = await fetch(
`${BASE_URL}/v2/pets:identify`,
{
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ sessionId })
}
);
const jobId = (await response.json()).data.jobId;
console.log(`Identification job started: ${jobId}`);
// Poll for job status
while (true) {
const statusResponse = await fetch(
`${BASE_URL}/v2/identification-jobs/${jobId}`,
{ headers }
);
const result = (await statusResponse.json()).data;
if (result.status === "SUCCESS") {
const pets = result.pets || [];
console.log(`Found ${pets.length} matching pet(s)`);
pets.forEach(pet => {
console.log(` - ${pet.id}: score=${pet.score}`);
});
return result;
} else if (result.status === "FAILED") {
throw new Error(`Identification failed: ${result.error}`);
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
// Usage example
const result = await identifyPet("session-uuid-abcd");
if (result.pets?.length > 0) {
const bestMatch = result.pets[0];
console.log(`Best match: ${bestMatch.id} (score: ${bestMatch.score})`);
} else {
console.log("No matching pets found");
}Identification Result Response
{
"data": {
"status": "SUCCESS",
"pets": [
{
"id": "pet-uuid-1234",
"score": 95,
"metadata": "{\"name\": \"Buddy\", \"owner\": \"John Doe\"}"
},
{
"id": "pet-uuid-5678",
"score": 78,
"metadata": "{\"name\": \"Max\", \"owner\": \"Jane Smith\"}"
}
]
}
}| Field | Type | Description |
|---|---|---|
pets | array | Matched pets list (sorted by score descending) |
pets[].id | string | Pet ID |
pets[].score | number | Confidence score (0-100) |
pets[].metadata | string | Pet metadata (JSON string) |
Job Status Values
All async jobs have the following statuses:
| Status | Description |
|---|---|
PENDING | Processing |
SUCCESS | Completed successfully |
FAILED | Failed |
Recommended Polling Settings
| Item | Recommended Value |
|---|---|
| Polling Interval | 2-3 seconds |
| Max Wait Time | 60 seconds |
| Max Retry Count | 20-30 times |
Tip: Using exponential backoff can reduce server load and make polling more efficient. We recommend starting at 1 second and increasing up to 5 seconds maximum.