Engines and prices
The engines
Three engines read the certificate: mini and large, the standard engines, answer every request. fast answers first when the request asks for it with "engine": "fast"; if it cannot answer, the standard engines follow. The answer says which engine answered, in engine.
bash
#!/usr/bin/env bash
# Ask for the fast engine: it is tried first, at its own price, and the
# standard engines follow when it cannot answer. The answer names the engine
# that answered and what it cost. Needs DOCSOCR_API_KEY in the environment.
set -euo pipefail
REQUEST_ID="fast-$(date +%s)-$RANDOM" # one id per document
# The API answers within 90 s
curl -sS --max-time 120 https://api.docsocr.com/api/v1/documents/birth-certificate \
-H "Authorization: Bearer $DOCSOCR_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"imageType": "url",
"imageUrl": "https://docsocr.com/samples/certidao-nascimento-exemplo.jpg",
"requestId": "$REQUEST_ID",
"engine": "fast"
}
EOFpy
"""Ask for the fast engine: it is tried first, at its own price, and the
standard engines follow when it cannot answer. The answer names the engine
that answered and what it cost.
Needs the requests package and DOCSOCR_API_KEY in the environment.
"""
import os
import uuid
import requests
response = requests.post(
"https://api.docsocr.com/api/v1/documents/birth-certificate",
headers={"Authorization": f"Bearer {os.environ['DOCSOCR_API_KEY']}"},
json={
"imageType": "url",
"imageUrl": "https://docsocr.com/samples/certidao-nascimento-exemplo.jpg",
"requestId": str(uuid.uuid4()), # one id per document
"engine": "fast",
},
timeout=120, # above the API's 90 s extraction budget
)
answer = response.json()
if response.status_code != 201 or not answer["success"]:
raise SystemExit(f"{response.status_code} {answer.get('errorCode', '')} {answer.get('message') or answer.get('error')}")
print("engine:", answer["engine"], "credits:", answer["creditsCharged"])js
// Ask for the fast engine: it is tried first, at its own price, and the
// standard engines follow when it cannot answer. The answer names the engine
// that answered and what it cost.
// Needs Node.js 18+ and DOCSOCR_API_KEY in the environment.
import { randomUUID } from 'node:crypto'
const response = await fetch('https://api.docsocr.com/api/v1/documents/birth-certificate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.DOCSOCR_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
imageType: 'url',
imageUrl: 'https://docsocr.com/samples/certidao-nascimento-exemplo.jpg',
requestId: randomUUID(), // one id per document
engine: 'fast',
}),
signal: AbortSignal.timeout(120_000), // above the API's 90 s extraction budget
})
const answer = await response.json()
if (response.status !== 201 || !answer.success) {
console.error(response.status, answer.errorCode ?? '', answer.message ?? answer.error)
process.exit(1)
}
console.log('engine:', answer.engine, 'credits:', answer.creditsCharged)php
<?php
// Ask for the fast engine: it is tried first, at its own price, and the
// standard engines follow when it cannot answer. The answer names the engine
// that answered and what it cost.
// Needs the curl extension and DOCSOCR_API_KEY in the environment.
$request = curl_init('https://api.docsocr.com/api/v1/documents/birth-certificate');
curl_setopt_array($request, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 120, // above the API's 90 s extraction budget
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DOCSOCR_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'imageType' => 'url',
'imageUrl' => 'https://docsocr.com/samples/certidao-nascimento-exemplo.jpg',
'requestId' => bin2hex(random_bytes(16)), // one id per document
'engine' => 'fast',
]),
]);
$body = curl_exec($request);
if ($body === false) {
fwrite(STDERR, curl_error($request) . PHP_EOL);
exit(1);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$answer = json_decode($body, true);
if ($status !== 201 || empty($answer['success'])) {
fwrite(STDERR, "$status " . ($answer['errorCode'] ?? '') . ' ' . implode('; ', (array) ($answer['message'] ?? $answer['error'] ?? '')) . PHP_EOL);
exit(1);
}
echo 'engine: ', $answer['engine'], ' credits: ', $answer['creditsCharged'], PHP_EOL;java
// Ask for the fast engine: it is tried first, at its own price, and the
// standard engines follow when it cannot answer. The answer names the engine
// that answered and what it cost.
// Needs Java 17+ and DOCSOCR_API_KEY in the environment. Run: java Fast.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.UUID;
public class Fast {
public static void main(String[] args) throws Exception {
String body = """
{
"imageType": "url",
"imageUrl": "https://docsocr.com/samples/certidao-nascimento-exemplo.jpg",
"requestId": "%s",
"engine": "fast"
}""".formatted(UUID.randomUUID()); // one id per document
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.docsocr.com/api/v1/documents/birth-certificate"))
.timeout(Duration.ofSeconds(120)) // above the API's 90 s extraction budget
.header("Authorization", "Bearer " + System.getenv("DOCSOCR_API_KEY"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
// The answer is JSON: engine and creditsCharged say who answered and the cost
System.out.println(response.body());
if (response.statusCode() != 201 || !response.body().contains("\"success\":true")) {
System.exit(1);
}
}
}csharp
// Ask for the fast engine: it is tried first, at its own price, and the
// standard engines follow when it cannot answer. The answer names the engine
// that answered and what it cost.
// Needs .NET 8+ and DOCSOCR_API_KEY in the environment. Run: dotnet run Fast.cs (.NET 10)
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(120) }; // above the API's 90 s extraction budget
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("DOCSOCR_API_KEY"));
var body = new JsonObject
{
["imageType"] = "url",
["imageUrl"] = "https://docsocr.com/samples/certidao-nascimento-exemplo.jpg",
["requestId"] = Guid.NewGuid().ToString(), // one id per document
["engine"] = "fast",
};
using var content = new StringContent(body.ToJsonString(), Encoding.UTF8, "application/json");
using var response = await http.PostAsync("https://api.docsocr.com/api/v1/documents/birth-certificate", content);
using var answer = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
var root = answer.RootElement;
if ((int)response.StatusCode != 201 || !root.GetProperty("success").GetBoolean())
{
Console.Error.WriteLine($"{(int)response.StatusCode} {root}");
return 1;
}
Console.WriteLine($"engine: {root.GetProperty("engine").GetString()} credits: {root.GetProperty("creditsCharged")}");
return 0;What it costs
- 1 credit per answer with data, on the standard engines.
- With
"engine": "fast", fast's price when it answers, and 1 credit when a standard engine answers instead. resizeImage: 1 extra credit when the image is resized. See Image standard.
fast's price may change: read it live at GET /documents/prices, which needs no key.
bash
#!/usr/bin/env bash
# The price of an extraction, in credits, per engine and for resizeImage.
# A public endpoint: no key needed.
set -euo pipefail
curl -sS --max-time 30 https://api.docsocr.com/api/v1/documents/pricespy
"""The price of an extraction, in credits, per engine and for resizeImage.
A public endpoint: no key needed. Needs the requests package.
"""
import requests
response = requests.get("https://api.docsocr.com/api/v1/documents/prices", timeout=30)
response.raise_for_status()
for name, credits in response.json().items():
print(f"{name}: {credits} credit(s)")js
// The price of an extraction, in credits, per engine and for resizeImage.
// A public endpoint: no key needed. Needs Node.js 18+.
const response = await fetch('https://api.docsocr.com/api/v1/documents/prices', {
signal: AbortSignal.timeout(30_000),
})
if (!response.ok) {
console.error(response.status)
process.exit(1)
}
for (const [name, credits] of Object.entries(await response.json())) {
console.log(`${name}: ${credits} credit(s)`)
}php
<?php
// The price of an extraction, in credits, per engine and for resizeImage.
// A public endpoint: no key needed. Needs the curl extension.
$request = curl_init('https://api.docsocr.com/api/v1/documents/prices');
curl_setopt_array($request, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30]);
$body = curl_exec($request);
if ($body === false || curl_getinfo($request, CURLINFO_RESPONSE_CODE) !== 200) {
fwrite(STDERR, 'The price list did not answer' . PHP_EOL);
exit(1);
}
foreach (json_decode($body, true) as $name => $credits) {
echo "$name: $credits credit(s)", PHP_EOL;
}java
// The price of an extraction, in credits, per engine and for resizeImage.
// A public endpoint: no key needed. Needs Java 17+. Run: java Prices.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class Prices {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.docsocr.com/api/v1/documents/prices"))
.timeout(Duration.ofSeconds(30))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
// The answer is JSON, e.g. {"standard": 1, ...}; read it with your JSON library
System.out.println(response.body());
if (response.statusCode() != 200) {
System.exit(1);
}
}
}csharp
// The price of an extraction, in credits, per engine and for resizeImage.
// A public endpoint: no key needed. Needs .NET 8+. Run: dotnet run Prices.cs (.NET 10)
using System.Text.Json;
using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var prices = JsonDocument.Parse(await http.GetStringAsync("https://api.docsocr.com/api/v1/documents/prices"));
foreach (var price in prices.RootElement.EnumerateObject())
{
Console.WriteLine($"{price.Name}: {price.Value} credit(s)");
}What costs nothing
- A refused request, with 400 or 422.
- A request no engine could serve: the answer is 201 with
success: false. - A repeat answered from its kept answer. See Request IDs and retries.
What it cost
Each answer says what it cost, in creditsCharged, to the hundredth. When the balance cannot pay the request, the answer is 402 NOT_ENOUGH_CREDITS and nothing runs. Your balance and credit purchases are in the panel.