Petnow LogoPetnow

Biometric Upload

Upload fingerprint (nose) and appearance images using the Petnow API.

Overview

This API allows you to upload pet biometric data (fingerprint/nose images, appearance images). You must create a capture session before uploading.

Create Capture Session

Create a capture session before uploading biometric data.

Endpoint: POST /v2/capture-sessions

Request

curl -X POST "https://api.b2b.petnow.io/v2/capture-sessions" \
  -H "x-petnow-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "species": "DOG",
    "purpose": "PET_PROFILE_REGISTRATION",
    "petId": "pet-uuid-1234"
  }'
import requests

url = "https://api.b2b.petnow.io/v2/capture-sessions"
headers = {
    "x-petnow-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}
data = {
    "species": "DOG",
    "purpose": "PET_PROFILE_REGISTRATION",
    "petId": "pet-uuid-1234"
}

response = requests.post(url, headers=headers, json=data)
result = response.json()
session_id = result["data"]["id"]
print(f"Session ID: {session_id}")
const response = await fetch("https://api.b2b.petnow.io/v2/capture-sessions", {
  method: "POST",
  headers: {
    "x-petnow-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    species: "DOG",
    purpose: "PET_PROFILE_REGISTRATION",
    petId: "pet-uuid-1234"
  })
});

const result = await response.json();
const sessionId = result.data.id;
console.log(`Session ID: ${sessionId}`);

Request Parameters

FieldTypeRequiredDescription
speciesstringSpecies: DOG or CAT
purposestringPurpose (see table below)
petIdstringConditionalRequired for registration/verification

Purpose Values

PurposeDescriptionPet ID
PET_PROFILE_REGISTRATIONRegister new petRequired
PET_VERIFICATIONVerify specific pet (1:1)Required
PET_IDENTIFICATIONIdentify pet (1:N)Not required

Response

{
  "data": {
    "id": "session-uuid-abcd"
  }
}

Upload Fingerprint (Nose) Image

Upload a pet's nose (fingerprint) image.

Endpoint: POST /v2/fingerprints:upload?sessionId={sessionId}

Required: The sessionId query parameter is always required. Uploaded files are automatically linked to the session.

Request

curl -X POST "https://api.b2b.petnow.io/v2/fingerprints:upload?sessionId=session-uuid-abcd" \
  -H "x-petnow-api-key: YOUR_API_KEY" \
  -F "file=@/path/to/nose_image.jpg"
import requests

session_id = "session-uuid-abcd"
url = f"https://api.b2b.petnow.io/v2/fingerprints:upload?sessionId={session_id}"
headers = {
    "x-petnow-api-key": "YOUR_API_KEY"
}

with open("/path/to/nose_image.jpg", "rb") as f:
    files = {"file": ("nose_image.jpg", f, "image/jpeg")}
    response = requests.post(url, headers=headers, files=files)

result = response.json()
fingerprint_id = result["data"]["id"]
print(f"Fingerprint ID: {fingerprint_id}")
const sessionId = "session-uuid-abcd";
const formData = new FormData();
formData.append("file", fileBlob, "nose_image.jpg");

const response = await fetch(
  `https://api.b2b.petnow.io/v2/fingerprints:upload?sessionId=${sessionId}`,
  {
    method: "POST",
    headers: {
      "x-petnow-api-key": "YOUR_API_KEY"
    },
    body: formData
  }
);

const result = await response.json();
const fingerprintId = result.data.id;
console.log(`Fingerprint ID: ${fingerprintId}`);

Request Parameters

FieldTypeRequiredDescription
sessionIdstring (query)Capture session ID
filefileFingerprint (nose) image file (JPEG)

Response

{
  "data": {
    "id": "fingerprint-uuid-1234"
  }
}

Upload Count: Minimum 5 images for registration, minimum 3 images for verification/identification. More images improve recognition accuracy.

Upload Appearance Image

Upload a pet's full appearance image.

Endpoint: POST /v2/appearances:upload?sessionId={sessionId}

Request

curl -X POST "https://api.b2b.petnow.io/v2/appearances:upload?sessionId=session-uuid-abcd" \
  -H "x-petnow-api-key: YOUR_API_KEY" \
  -F "file=@/path/to/pet_photo.jpg"
import requests

session_id = "session-uuid-abcd"
url = f"https://api.b2b.petnow.io/v2/appearances:upload?sessionId={session_id}"
headers = {
    "x-petnow-api-key": "YOUR_API_KEY"
}

with open("/path/to/pet_photo.jpg", "rb") as f:
    files = {"file": ("pet_photo.jpg", f, "image/jpeg")}
    response = requests.post(url, headers=headers, files=files)

result = response.json()
appearance_id = result["data"]["id"]
print(f"Appearance ID: {appearance_id}")
const sessionId = "session-uuid-abcd";
const formData = new FormData();
formData.append("file", fileBlob, "pet_photo.jpg");

const response = await fetch(
  `https://api.b2b.petnow.io/v2/appearances:upload?sessionId=${sessionId}`,
  {
    method: "POST",
    headers: {
      "x-petnow-api-key": "YOUR_API_KEY"
    },
    body: formData
  }
);

const result = await response.json();
const appearanceId = result.data.id;
console.log(`Appearance ID: ${appearanceId}`);

Request Parameters

FieldTypeRequiredDescription
sessionIdstring (query)Capture session ID
filefileAppearance image file (JPEG)

Response

{
  "data": {
    "id": "appearance-uuid-5678"
  }
}

Complete Upload Flow Example

Automatic Session Linking: When uploading with the sessionId query parameter, files are automatically linked to the session. No separate session end API call is required.

import requests
from pathlib import Path

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.b2b.petnow.io"
HEADERS = {"x-petnow-api-key": API_KEY}

def upload_biometrics(pet_id: str, fingerprint_files: list, appearance_files: list):
    # 1. Create capture session
    session_response = requests.post(
        f"{BASE_URL}/v2/capture-sessions",
        headers={**HEADERS, "Content-Type": "application/json"},
        json={
            "species": "DOG",
            "purpose": "PET_PROFILE_REGISTRATION",
            "petId": pet_id
        }
    )
    session_id = session_response.json()["data"]["id"]
    print(f"Created session: {session_id}")

    # 2. Upload fingerprints (auto-linked via sessionId query parameter)
    fingerprint_ids = []
    for file_path in fingerprint_files:
        with open(file_path, "rb") as f:
            response = requests.post(
                f"{BASE_URL}/v2/fingerprints:upload?sessionId={session_id}",
                headers=HEADERS,
                files={"file": (Path(file_path).name, f, "image/jpeg")}
            )
            fp_id = response.json()["data"]["id"]
            fingerprint_ids.append(fp_id)
            print(f"Uploaded fingerprint: {fp_id}")

    # 3. Upload appearances (auto-linked via sessionId query parameter)
    appearance_ids = []
    for file_path in appearance_files:
        with open(file_path, "rb") as f:
            response = requests.post(
                f"{BASE_URL}/v2/appearances:upload?sessionId={session_id}",
                headers=HEADERS,
                files={"file": (Path(file_path).name, f, "image/jpeg")}
            )
            ap_id = response.json()["data"]["id"]
            appearance_ids.append(ap_id)
            print(f"Uploaded appearance: {ap_id}")

    return session_id, fingerprint_ids, appearance_ids

# Usage example
session_id, fp_ids, ap_ids = upload_biometrics(
    pet_id="pet-uuid-1234",
    fingerprint_files=["nose1.jpg", "nose2.jpg", "nose3.jpg", "nose4.jpg", "nose5.jpg"],
    appearance_files=["full_body.jpg"]
)
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://api.b2b.petnow.io";

async function uploadBiometrics(petId, fingerprintFiles, appearanceFiles) {
  const headers = { "x-petnow-api-key": API_KEY };

  // 1. Create capture session
  const sessionResponse = await fetch(`${BASE_URL}/v2/capture-sessions`, {
    method: "POST",
    headers: { ...headers, "Content-Type": "application/json" },
    body: JSON.stringify({
      species: "DOG",
      purpose: "PET_PROFILE_REGISTRATION",
      petId: petId
    })
  });
  const sessionId = (await sessionResponse.json()).data.id;
  console.log(`Created session: ${sessionId}`);

  // 2. Upload fingerprints (auto-linked via sessionId query parameter)
  const fingerprintIds = [];
  for (const file of fingerprintFiles) {
    const formData = new FormData();
    formData.append("file", file);

    const response = await fetch(
      `${BASE_URL}/v2/fingerprints:upload?sessionId=${sessionId}`,
      {
        method: "POST",
        headers: headers,
        body: formData
      }
    );
    const fpId = (await response.json()).data.id;
    fingerprintIds.push(fpId);
    console.log(`Uploaded fingerprint: ${fpId}`);
  }

  // 3. Upload appearances (auto-linked via sessionId query parameter)
  const appearanceIds = [];
  for (const file of appearanceFiles) {
    const formData = new FormData();
    formData.append("file", file);

    const response = await fetch(
      `${BASE_URL}/v2/appearances:upload?sessionId=${sessionId}`,
      {
        method: "POST",
        headers: headers,
        body: formData
      }
    );
    const apId = (await response.json()).data.id;
    appearanceIds.push(apId);
    console.log(`Uploaded appearance: ${apId}`);
  }

  return { sessionId, fingerprintIds, appearanceIds };
}

Next Steps

On this page