API docs
A small JSON API. Base URL https://opentrust.in/api/v1. Create your key from your dashboard.
Libraries
Small, dependency-free clients that wrap this API with typed errors, so you can be up and running in a few lines. They're open source.
The Ruby and Node packages are about to be published. Until then you can call the API directly with any HTTP client, as shown below.
gem install opentrust
client = OpenTrust::Client.new
client.lookup("9876543210").reported?npm install opentrust
const ot = new OpenTrust();
(await ot.lookup("9876543210")).reportedBoth read OPENTRUST_API_KEY from the environment. See all libraries and integrations, including the Shopify and WooCommerce plugins on the way. Want a library for another language? Tell us.
Authentication
Send your key as a bearer token on every request. Keep it secret and revoke it from the dashboard if it leaks. Requests are limited to 120 per minute per key.
Authorization: Bearer ot_live_xxxxxxxxxxxxxxxxxxxxxxxxPOST /lookups
Check one number. Uses 1 check from your allowance. Any common format works: 98765 43210, 09876543210 or +919876543210.
curl -X POST https://opentrust.in/api/v1/lookups \
-H "Authorization: Bearer $OPENTRUST_KEY" \
-d phone=9876543210const res = await fetch("https://opentrust.in/api/v1/lookups", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENTRUST_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ phone: "9876543210" }),
});
const result = await res.json();import os, requests
res = requests.post(
"https://opentrust.in/api/v1/lookups",
headers={"Authorization": f"Bearer {os.environ['OPENTRUST_KEY']}"},
json={"phone": "9876543210"},
)
result = res.json()$ch = curl_init("https://opentrust.in/api/v1/lookups");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("OPENTRUST_KEY"),
"Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode(["phone" => "9876543210"]),
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);require "net/http"
require "json"
uri = URI("https://opentrust.in/api/v1/lookups")
req = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{ENV['OPENTRUST_KEY']}",
"Content-Type" => "application/json")
req.body = { phone: "9876543210" }.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |h| h.request(req) }
result = JSON.parse(res.body)
Response 200
{
"phone_last4": "3210",
"reported": true,
"report_count": 1,
"reports": [
{
"reason_code": "cod_refusal",
"reason": "Refused a cash-on-delivery order",
"notes": "Refused 3 COD orders",
"reported_at": "2026-10-01",
"reporter_verified": true
}
],
"notice": "Reports are unverified observations shared by individual merchants. …",
"checks_remaining": 99999
}- reports: [] and report_count: 0 mean no merchant has reported the number.
- You never get the full number back, only phone_last4, and never who reported.
- notice is included in every response. Please keep it in front of anyone who sees a result.
POST /lookups/batch
Check up to 100 numbers. Uses one check per number, all or nothing: if you don't have enough checks, none are used and you get a 402.
curl -X POST https://opentrust.in/api/v1/lookups/batch \
-H "Authorization: Bearer $OPENTRUST_KEY" \
-H "Content-Type: application/json" \
-d '{"phones": ["9876543210", "9000000001"]}'Response 200
{
"results": [
{
"phone_last4": "3210",
"reported": true,
"report_count": 1,
"reports": [
"…"
]
},
{
"phone_last4": "0001",
"reported": false,
"report_count": 0,
"reports": [
]
}
],
"notice": "…",
"checks_remaining": 99998
}GET /me
See your checks. Free to call.
{
"merchant": "Your Shop",
"checks_remaining": 99998,
"reports_submitted": 3
}Running low? Write to [email protected] and we'll set a generous limit.
Errors
Every error has the same shape:
{
"error": {
"code": "no_checks_remaining",
"message": "You have used all your checks. …"
}
}| 401 | invalid_api_key | Missing or invalid API key |
| 402 | no_checks_remaining | No checks left. Write to us and we'll raise your limit |
| 403 | merchant_not_approved | Account isn't approved or is suspended |
| 409 | duplicate_report | You already shared this number |
| 422 | invalid_phone / invalid_report | Invalid number, reason code or note |
| 429 | rate_limited | Over 120 requests per minute |
Using results responsibly
Reports are unverified observations shared by individual merchants. They are not a finding that anyone committed fraud. Use them as one input among others, not as the sole reason to refuse a customer.
- Have a person review any decision that materially affects a customer.
- Don't tell customers that OpenTrust is the reason for a decision.
- Don't resell, republish or bulk-export results. See the Terms.