API reference
Four calls: enroll, identify, delete and list cows. Pick a language on the right, or try a call in the sandbox without leaving the page.
Overview
Four calls, all on https://api.central.pranisheba.com.bd. Authenticate every call with your key in the X-API-Key header. Photos are limited to 20 MB, are passed to the model and are never stored by this platform.
Responses are passed through as returned by the identification model, with the same JSON and HTTP status. The platform adds headers and, for errors it raises itself, the envelope described on the errors page. The body of a live response is the model's own.
Endpoints
| Call | Parameters | Token |
| POST /enroll | multipart form: cow_id, file | 1 enroll token when the cow is enrolled |
| POST /identify | multipart form: file, optional top_k | 1 search token when the search runs |
| DELETE /delete/{cow_id} | none | free |
| GET /cows | query: optional limit, offset | free |
Enroll a cow
POST/enroll
Register a cow with a photo of its muzzle so it can be found later.
Cost: 1 enroll token when the cow is enrolled. Any error is free.
Parameters
cow_id string form required
- Your id for the cow. Must not be blank,
. or ...
file file form required
- The muzzle photo, up to 20 MB.
Responses
A 200 means the call worked. Check is_success and the HTTP status, and read X-Request-Id when you contact support.
Enroll a cow: errors
| Status | When |
| 400 | file is missing or cow_id is missing or invalid. |
|---|
| 402 | No enroll tokens left. |
|---|
| 413 | The photo is over 20 MB. |
|---|
| 429 | Rate or concurrency limit reached. |
|---|
| 502 | The model could not be reached. Nothing is charged. |
Request
cURL
curl -X POST https://api.central.pranisheba.com.bd/enroll \
-H "X-API-Key: YOUR_API_KEY" \
-F cow_id=BD-0001 \
-F file=@muzzle.jpg
Python
import requests
BASE_URL = "https://api.central.pranisheba.com.bd"
HEADERS = {"X-API-Key": "YOUR_API_KEY"}
with open("muzzle.jpg", "rb") as photo:
response = requests.post(
f"{BASE_URL}/enroll",
headers=HEADERS,
data={"cow_id": "BD-0001"},
files={"file": ("muzzle.jpg", photo, "image/jpeg")},
timeout=(10, 180),
)
print(response.status_code, response.headers.get("X-Tokens-Remaining"))
print(response.text)
JavaScript
import { readFile } from "node:fs/promises";
const BASE_URL = "https://api.central.pranisheba.com.bd";
const HEADERS = { "X-API-Key": "YOUR_API_KEY" };
const form = new FormData();
form.append("cow_id", "BD-0001");
form.append("file", new Blob([await readFile("muzzle.jpg")], { type: "image/jpeg" }), "muzzle.jpg");
const response = await fetch(`${BASE_URL}/enroll`, { method: "POST", headers: HEADERS, body: form });
console.log(response.status, response.headers.get("X-Tokens-Remaining"));
console.log(await response.json());
Sample response
What the sandbox returns. A live 200 comes from the identification model.
200 OK
{
"is_success": true,
"message": "Cow enrolled.",
"data": {
"cow_id": "BD-0001"
}
}
400
{
"is_success": false,
"message": "file is required.",
"data": null
}
402
{
"is_success": false,
"message": "No enroll tokens left. Buy more to continue.",
"data": null
}
429
{
"is_success": false,
"message": "Rate limit exceeded. Try again later.",
"data": null
}
Identify a cow
POST/identify
Find which enrolled cow a new muzzle photo belongs to.
Cost: 1 search token when the search runs, whether or not a match is found. Any error is free.
Parameters
file file form required
- The muzzle photo, up to 20 MB.
top_k integer form optional
- How many candidates to return, from 1 to 5. Default 1.
Responses
A 200 means the call worked. Check is_success and the HTTP status, and read X-Request-Id when you contact support.
Identify a cow: errors
| Status | When |
| 400 | file is missing, or top_k is not a whole number from 1 to 5. |
|---|
| 402 | No search tokens left. |
|---|
| 413 | The photo is over 20 MB. |
|---|
| 429 | Rate or concurrency limit reached. |
|---|
| 502 | The model could not be reached. Nothing is charged. |
Request
cURL
curl -X POST https://api.central.pranisheba.com.bd/identify \
-H "X-API-Key: YOUR_API_KEY" \
-F top_k=3 \
-F file=@muzzle.jpg
Python
import requests
BASE_URL = "https://api.central.pranisheba.com.bd"
HEADERS = {"X-API-Key": "YOUR_API_KEY"}
with open("muzzle.jpg", "rb") as photo:
response = requests.post(
f"{BASE_URL}/identify",
headers=HEADERS,
data={"top_k": 3},
files={"file": ("muzzle.jpg", photo, "image/jpeg")},
timeout=(10, 180),
)
print(response.status_code, response.headers.get("X-Tokens-Remaining"))
print(response.text)
JavaScript
import { readFile } from "node:fs/promises";
const BASE_URL = "https://api.central.pranisheba.com.bd";
const HEADERS = { "X-API-Key": "YOUR_API_KEY" };
const form = new FormData();
form.append("top_k", "3");
form.append("file", new Blob([await readFile("muzzle.jpg")], { type: "image/jpeg" }), "muzzle.jpg");
const response = await fetch(`${BASE_URL}/identify`, { method: "POST", headers: HEADERS, body: form });
console.log(response.status, response.headers.get("X-Tokens-Remaining"));
console.log(await response.json());
Sample response
What the sandbox returns. A live 200 comes from the identification model.
200 OK
{
"is_success": true,
"message": "Search complete.",
"data": {
"matches": [
{
"cow_id": "BD-0001",
"score": 0.97
},
{
"cow_id": "BD-0002",
"score": 0.91
},
{
"cow_id": "BD-0003",
"score": 0.84
}
]
}
}
400
{
"is_success": false,
"message": "top_k must be an integer between 1 and 5.",
"data": null
}
402
{
"is_success": false,
"message": "No search tokens left. Buy more to continue.",
"data": null
}
429
{
"is_success": false,
"message": "Rate limit exceeded. Try again later.",
"data": null
}
Delete a cow
DELETE/delete/{cow_id}
Remove a cow you enrolled.
Cost: Free.
Parameters
cow_id string path required
- The id you enrolled the cow with. Must not be blank,
. or ...
Responses
A 200 means the call worked. Check is_success and the HTTP status, and read X-Request-Id when you contact support.
Delete a cow: errors
| Status | When |
| 400 | cow_id is blank, . or ... |
|---|
| 429 | Rate or concurrency limit reached. |
|---|
| 502 | The model could not be reached. |
Request
cURL
curl -X DELETE https://api.central.pranisheba.com.bd/delete/BD-0001 \
-H "X-API-Key: YOUR_API_KEY"
Python
import requests
BASE_URL = "https://api.central.pranisheba.com.bd"
HEADERS = {"X-API-Key": "YOUR_API_KEY"}
response = requests.delete(f"{BASE_URL}/delete/BD-0001", headers=HEADERS, timeout=(10, 180))
print(response.status_code, response.text)
JavaScript
import { readFile } from "node:fs/promises";
const BASE_URL = "https://api.central.pranisheba.com.bd";
const HEADERS = { "X-API-Key": "YOUR_API_KEY" };
const response = await fetch(`${BASE_URL}/delete/BD-0001`, { method: "DELETE", headers: HEADERS });
console.log(response.status, await response.json());
Sample response
What the sandbox returns. A live 200 comes from the identification model.
200 OK
{
"is_success": true,
"message": "Cow deleted.",
"data": {
"cow_id": "BD-0001"
}
}
400
{
"is_success": false,
"message": "cow_id must not be blank, '.' or '..'.",
"data": null
}
429
{
"is_success": false,
"message": "Rate limit exceeded. Try again later.",
"data": null
}
List your cows
GET/cows
Page through the cows enrolled in your account.
Cost: Free.
Parameters
limit integer query optional
- How many cows to return, from 0 to 1000.
offset integer query optional
- How many cows to skip, 0 or more. Default 0.
Responses
A 200 means the call worked. Check is_success and the HTTP status, and read X-Request-Id when you contact support.
List your cows: errors
| Status | When |
| 400 | limit or offset is not a whole number in range. |
|---|
| 429 | Rate or concurrency limit reached. |
|---|
| 502 | The model could not be reached. |
Request
cURL
curl "https://api.central.pranisheba.com.bd/cows?limit=100&offset=0" \
-H "X-API-Key: YOUR_API_KEY"
Python
import requests
BASE_URL = "https://api.central.pranisheba.com.bd"
HEADERS = {"X-API-Key": "YOUR_API_KEY"}
response = requests.get(
f"{BASE_URL}/cows",
headers=HEADERS,
params={"limit": 100, "offset": 0},
timeout=(10, 180),
)
print(response.status_code, response.text)
JavaScript
import { readFile } from "node:fs/promises";
const BASE_URL = "https://api.central.pranisheba.com.bd";
const HEADERS = { "X-API-Key": "YOUR_API_KEY" };
const response = await fetch(`${BASE_URL}/cows?limit=100&offset=0`, { headers: HEADERS });
console.log(response.status, await response.json());
Sample response
What the sandbox returns. A live 200 comes from the identification model.
200 OK
{
"is_success": true,
"message": "Cows listed.",
"data": {
"cows": [
{
"cow_id": "BD-0001"
},
{
"cow_id": "BD-0002"
},
{
"cow_id": "BD-0003"
}
],
"total": 3,
"limit": 100,
"offset": 0
}
}
400
{
"is_success": false,
"message": "limit must be an integer between 0 and 1000.",
"data": null
}
429
{
"is_success": false,
"message": "Rate limit exceeded. Try again later.",
"data": null
}