Petnow LogoPetnow

Registration/Verification/Identification

Pet fingerprint registration, verification (1:1), and identification (1:N) API guide.

Overview

Petnow API provides three core features:

FeatureDescriptionUse Case
RegistrationAdd fingerprints to petRegister new pet
Verification1:1 matchingConfirm "Is this the right pet?"
Identification1:N matchingFind "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
  }
}
FieldTypeDescription
statusstringPENDING, SUCCESS, FAILED
isVerifiedbooleanWhether verification passed
scorenumberConfidence 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\"}"
      }
    ]
  }
}
FieldTypeDescription
petsarrayMatched pets list (sorted by score descending)
pets[].idstringPet ID
pets[].scorenumberConfidence score (0-100)
pets[].metadatastringPet metadata (JSON string)

Job Status Values

All async jobs have the following statuses:

StatusDescription
PENDINGProcessing
SUCCESSCompleted successfully
FAILEDFailed
ItemRecommended Value
Polling Interval2-3 seconds
Max Wait Time60 seconds
Max Retry Count20-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.

Next Steps

On this page