Petnow LogoPetnow
Server API

펫 관리 API

반려동물 프로필 생성, 조회, 수정, 삭제 API를 안내합니다.

개요

펫 관리 API를 통해 반려동물 프로필을 CRUD(생성, 조회, 수정, 삭제)할 수 있습니다.

펫 생성

새로운 반려동물 프로필을 생성합니다.

엔드포인트: POST /v2/pets

요청

curl -X POST "https://api.petify.petnow.io/v2/pets" \
  -H "x-petnow-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "species": "DOG",
    "breed": "골든 리트리버",
    "metadata": "{\"name\": \"버디\", \"age\": 3, \"owner\": \"홍길동\"}"
  }'
import requests
import json

url = "https://api.petify.petnow.io/v2/pets"
headers = {
    "x-petnow-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}
data = {
    "species": "DOG",
    "breed": "골든 리트리버",
    "metadata": json.dumps({
        "name": "버디",
        "age": 3,
        "owner": "홍길동"
    })
}

response = requests.post(url, headers=headers, json=data)
result = response.json()
print(result)
# {"success": true, "data": {"id": "pet-uuid-1234"}}
const response = await fetch("https://api.petify.petnow.io/v2/pets", {
  method: "POST",
  headers: {
    "x-petnow-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    species: "DOG",
    breed: "골든 리트리버",
    metadata: JSON.stringify({
      name: "버디",
      age: 3,
      owner: "홍길동"
    })
  })
});

const result = await response.json();
console.log(result);
// {success: true, data: {id: "pet-uuid-1234"}}

요청 파라미터

필드타입필수설명
speciesstring✅종류: DOG 또는 CAT
breedstring❌품종
metadatastring❌JSON 문자열 형태의 추가 정보

응답

{
  "success": true,
  "data": {
    "id": "pet-uuid-1234"
  }
}

메타데이터 활용: metadata 필드에 JSON 문자열로 이름, 나이, 소유자 정보 등 비즈니스에 필요한 추가 정보를 저장할 수 있습니다.

펫 목록 조회

등록된 모든 반려동물 목록을 조회합니다.

엔드포인트: GET /v2/pets

요청

curl -X GET "https://api.petify.petnow.io/v2/pets" \
  -H "x-petnow-api-key: YOUR_API_KEY"
import requests

url = "https://api.petify.petnow.io/v2/pets"
headers = {
    "x-petnow-api-key": "YOUR_API_KEY"
}

response = requests.get(url, headers=headers)
result = response.json()
print(result)
const response = await fetch("https://api.petify.petnow.io/v2/pets", {
  method: "GET",
  headers: {
    "x-petnow-api-key": "YOUR_API_KEY"
  }
});

const result = await response.json();
console.log(result);

응답

{
  "success": true,
  "data": [
    {
      "id": "pet-uuid-1234",
      "species": "DOG",
      "breed": "골든 리트리버",
      "metadata": "{\"name\": \"버디\", \"age\": 3}",
      "hasFingerprint": true,
      "createdAt": "2026-01-15T10:30:00Z"
    },
    {
      "id": "pet-uuid-5678",
      "species": "CAT",
      "breed": "러시안 블루",
      "metadata": "{\"name\": \"나비\", \"age\": 2}",
      "hasFingerprint": false,
      "createdAt": "2026-01-10T14:20:00Z"
    }
  ]
}

data는 pets 필드로 감싸지 않고 펫 배열을 직접 반환합니다. 각 항목에는 등록된 지문 보유 여부를 나타내는 hasFingerprint(boolean)가 포함됩니다.

펫 상세 조회

특정 반려동물의 상세 정보를 조회합니다.

엔드포인트: GET /v2/pets/{petId}

요청

curl -X GET "https://api.petify.petnow.io/v2/pets/pet-uuid-1234" \
  -H "x-petnow-api-key: YOUR_API_KEY"
import requests

pet_id = "pet-uuid-1234"
url = f"https://api.petify.petnow.io/v2/pets/{pet_id}"
headers = {
    "x-petnow-api-key": "YOUR_API_KEY"
}

response = requests.get(url, headers=headers)
result = response.json()
print(result)
const petId = "pet-uuid-1234";
const response = await fetch(`https://api.petify.petnow.io/v2/pets/${petId}`, {
  method: "GET",
  headers: {
    "x-petnow-api-key": "YOUR_API_KEY"
  }
});

const result = await response.json();
console.log(result);

응답

{
  "success": true,
  "data": {
    "id": "pet-uuid-1234",
    "species": "DOG",
    "breed": "골든 리트리버",
    "metadata": "{\"name\": \"버디\", \"age\": 3, \"owner\": \"홍길동\"}",
    "hasFingerprint": true,
    "createdAt": "2026-01-15T10:30:00Z"
  }
}

응답 필드

필드타입설명
idstring펫 ID
speciesstringDOG 또는 CAT
breedstring품종
metadatastringJSON 문자열 형태의 추가 정보
hasFingerprintboolean등록된 지문 보유 여부
createdAtstring생성 시각 (ISO 8601)

펫 정보 수정

반려동물의 메타데이터를 수정합니다.

엔드포인트: PATCH /v2/pets/{petId}

요청

curl -X PATCH "https://api.petify.petnow.io/v2/pets/pet-uuid-1234" \
  -H "x-petnow-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "breed": "골든 리트리버 믹스",
    "metadata": "{\"name\": \"버디\", \"age\": 4, \"owner\": \"홍길동\", \"vaccinated\": true}"
  }'
import requests
import json

pet_id = "pet-uuid-1234"
url = f"https://api.petify.petnow.io/v2/pets/{pet_id}"
headers = {
    "x-petnow-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}
data = {
    "breed": "골든 리트리버 믹스",
    "metadata": json.dumps({
        "name": "버디",
        "age": 4,
        "owner": "홍길동",
        "vaccinated": True
    })
}

response = requests.patch(url, headers=headers, json=data)
result = response.json()
print(result)
const petId = "pet-uuid-1234";
const response = await fetch(`https://api.petify.petnow.io/v2/pets/${petId}`, {
  method: "PATCH",
  headers: {
    "x-petnow-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    breed: "골든 리트리버 믹스",
    metadata: JSON.stringify({
      name: "버디",
      age: 4,
      owner: "홍길동",
      vaccinated: true
    })
  })
});

const result = await response.json();
console.log(result);

요청 파라미터

필드타입필수설명
metadatastring✅JSON 문자열 형태의 추가 정보
breedstring❌품종

응답

{
  "success": true,
  "data": {
    "isSuccessful": true
  }
}

수정 API는 { "isSuccessful": true }만 반환하며, 수정된 펫 객체를 되돌려주지 않습니다. 수정된 값이 필요하면 이후 펫 상세 조회를 호출하세요.

펫 삭제

반려동물 프로필을 삭제합니다. 삭제된 펫은 즉시 검증·식별 대상에서 제외되며, 과금 기준의 등록 펫 수에도 더 이상 포함되지 않습니다. 같은 펫으로 서비스를 다시 사용하려면 재등록(새 프로필 생성과 새 촬영)이 필요합니다.

엔드포인트: DELETE /v2/pets/{petId}

요청

curl -X DELETE "https://api.petify.petnow.io/v2/pets/pet-uuid-1234" \
  -H "x-petnow-api-key: YOUR_API_KEY"
import requests

pet_id = "pet-uuid-1234"
url = f"https://api.petify.petnow.io/v2/pets/{pet_id}"
headers = {
    "x-petnow-api-key": "YOUR_API_KEY"
}

response = requests.delete(url, headers=headers)
print(response.status_code)  # 204 No Content
const petId = "pet-uuid-1234";
const response = await fetch(`https://api.petify.petnow.io/v2/pets/${petId}`, {
  method: "DELETE",
  headers: {
    "x-petnow-api-key": "YOUR_API_KEY"
  }
});

console.log(response.status);  // 204 No Content

응답

성공 시 204 No Content를 반환합니다.

주의: 고객사 입장에서 삭제는 되돌릴 수 없습니다 — 복구 API가 없으므로 호출 전에 petId를 확인하세요.

이미 삭제된 펫을 다시 삭제하면 404와 PETNOWB2B20000이 반환되므로, 반복 호출해도 안전합니다.

Web Integration으로 생성된 펫

Web Integration으로 등록된 펫은 고객사의 externalPetId로만 참조되며 Petify petId가 노출되지 않으므로, 이 API로는 삭제할 수 없습니다. Petify Console의 생체 등록 결과(Biometric Registration Results) 에서 externalPetId로 검색해 삭제하세요 (Petify Console 참고). 콘솔 삭제는 DELETE /v2/pets/{petId}와 동일한 효과를 가집니다: 펫이 즉시 매칭 대상에서 제외되고 해당 externalPetId는 다시 등록에 사용할 수 있게 됩니다.

고객사 쪽에 externalPetId ↔ 회원 매핑을 반드시 보관하세요. Web Integration 펫을 다룰 유일한 식별자이며, 회원 탈퇴 시 레코드를 찾아 삭제하는 데 필요합니다.

미완료 레코드 정리

POST /v2/pets가 성공한 뒤 등록 플로우가 중단되면 — 예를 들어 업로드나 addFingerprints 단계가 실패하면 — 펫 프로필이 hasFingerprint: false 상태로 남습니다. 이런 펫은 생체 정보가 없지만 과금 스냅샷 시점에는 등록된 펫으로 집계됩니다. 방치하지 말고 삭제하세요:

  1. GET /v2/pets로 펫 목록을 조회합니다.
  2. hasFingerprint == false인 항목을 골라냅니다 (등록이 아직 진행 중인 프로필은 제외).
  3. 각각 DELETE /v2/pets/{petId}를 호출합니다. 204는 삭제 완료, 404 PETNOWB2B20000은 이미 삭제된 것이므로 재실행해도 안전합니다.
curl -s "https://api.petify.petnow.io/v2/pets" \
  -H "x-petnow-api-key: YOUR_API_KEY" \
| jq -r '.data[] | select(.hasFingerprint == false) | .id' \
| while read -r pet_id; do
    curl -s -o /dev/null -w "$pet_id %{http_code}\n" -X DELETE \
      "https://api.petify.petnow.io/v2/pets/$pet_id" \
      -H "x-petnow-api-key: YOUR_API_KEY"
  done

프로필 생성 후 등록 플로우가 실패하면 에러 처리에서 바로 DELETE를 호출하고, hasFingerprint: false 프로필이 남아 있는지 주기적으로(예: 결제일 전마다) 점검하는 것을 권장합니다.

회원 탈퇴 체크리스트

회원이 서비스를 떠나면 해당 펫이 매칭되지도, 과금되지도 않도록 삭제하세요:

  1. 고객사 매핑에서 펫의 petId를 찾습니다 (또는 GET /v2/pets에서 metadata로 대조).
  2. DELETE /v2/pets/{petId}를 호출합니다.
  3. 응답이 204인지 확인합니다 (이미 삭제된 경우 404 PETNOWB2B20000).
  4. 고객사 쪽 매핑을 제거합니다.

Web Integration으로 등록된 펫은 1–3단계를 위의 콘솔 삭제로 대체하세요.

메타데이터 스키마 예시

metadata 필드에 저장할 정보의 예시입니다:

{
  "name": "버디",
  "age": 3,
  "gender": "male",
  "owner": {
    "name": "홍길동",
    "phone": "010-1234-5678",
    "email": "user@example.com"
  },
  "vaccinated": true,
  "registrationNumber": "123456789",
  "notes": "알러지 있음"
}

팁: 메타데이터는 JSON 문자열로 저장되므로, 조회 시 파싱하여 사용하세요. 필드명과 구조는 비즈니스 요구사항에 맞게 자유롭게 정의할 수 있습니다.

다음 단계

On this page