К содержанию

Build with the Peryn API

OpenAI-compatible chat and text completions. Keep your OpenAI SDK code; change the base URL and the key.

Quickstart#

Three steps to your first answer.

  1. Войти with your email and add credit under Add credits.
  2. Create a key under API keys. It is shown once; we store only a hash of it. Keep it in the PERYN_API_KEY environment variable.
  3. Point any OpenAI SDK at the base URL and send a request.
curl https://api.peryn.ai/v1/chat/completions \-H "Authorization: Bearer $PERYN_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "llama-3.1-8b-instruct","max_tokens": 64,"messages": [{"role": "user", "content": "Say hello in five words."}]}'

The answer has the OpenAI shape, with the token counts you pay for in usage:

Response
{"id": "chatcmpl-…","object": "chat.completion","created": 1791216000,"model": "llama-3.1-8b-instruct","choices": [{"index": 0,"message": { "role": "assistant", "content": "Hello. Nice to meet you." },"logprobs": null,"finish_reason": "stop"}],"usage": { "prompt_tokens": 16, "completion_tokens": 8, "total_tokens": 24 }}
  1. Your code

    Any OpenAI SDK, our base URL, your API key.

  2. Our gateway

    Checks the key, the rate limits and your credit, then picks a GPU.

  3. A GPU node

    Runs the model. Standard GPUs also mine $PEARL.

Your request goes to our gateway, which checks it and sends it to a GPU node; the answer comes back the same way. We store no prompts or answers on the way.

Base URL and models#

One base URL for every endpoint. Send your key as a Bearer token.

Base URL
https://api.peryn.ai/v1

Every request that runs a model needs the header Authorization: Bearer <key>. Production keys start with pc_live_. Bodies are JSON, up to 2 MB.

https://api.peryn.ai/v1

  • POST/chat/completionsChat completions, streamed or not.API key
  • POST/completionsText completions from one prompt string.API key
  • GET/modelsEvery model: id, context, price.No key
  • GET/models/{id}One model.No key
  • GET/catalogEvery model with its price per million tokens, context length and licence.No key
  • GET/catalog/{id}One model from the catalog.No key
curl https://api.peryn.ai/v1/models

Request fields

The fields below are read; other OpenAI fields that do not change the answer (such as user or metadata) are ignored.

model
A model id from the table below. Required.
messages
Chat only. 1 to 2,048 messages; roles system, developer, user, assistant and tool; text content (a string or text parts). An assistant message can carry tool_calls (up to 128, arguments up to 256 KB each); a tool message needs its tool_call_id (up to 256 characters).
prompt
Text completions only. One string.
max_tokens
Output limit, 1 up to the model’s max output. max_completion_tokens works the same and wins if both are set.
stream
true for server-sent events.
stream_options
{"include_usage": true} adds a last chunk with token counts.
temperature
0 to 2.
top_p
Above 0, up to 1.
top_k
An integer, -1 or more.
min_p
0 to 1.
frequency_penalty, presence_penalty
-2 to 2.
repetition_penalty
Above 0, up to 2.
seed
An integer.
stop
A string or up to 4 strings, 256 characters each.
logit_bias
Token id to bias, -100 to 100.
response_format
Chat only. type text, json_object or json_schema. json_schema takes a name (1 to 64 letters, digits, _ or -) and your JSON Schema in schema, up to 64 KB and 64 levels deep.
tools
Chat only. Up to 128 functions. A name is 1 to 64 letters, digits, _ or -; a description up to 8,192 characters; parameters a JSON Schema up to 64 KB.
tool_choice
none, auto, required, or {"type": "function", "function": {"name": …}} naming one of your tools.
parallel_tool_calls
true or false.
logprobs
Chat: true or false. Text completions: 0 to 5.
top_logprobs
Chat only. 0 to 20, with logprobs: true.
n, best_of
1.

Models take text in and give text out. Images and other non-text content, n or best_of other than 1, echo, suffix, token-id prompts, more than one prompt per request, and the older functions and function_call fields (use tools and tool_choice) are answered with a 400 that names the field. If you need one of them, talk to us. Each model lists the optional fields it supports in supported_parameters on GET /v1/models.

Tool calling

The API takes tools, tool_choice, parallel_tool_calls and messages with role tool in the OpenAI format and passes them to the model. No model in this release declares tool calling. A model that does not declare it may refuse the request: tool_choice auto, the default when you send tools, is answered with a 400, code bad_request, and the model’s reason.

Structured outputs

response_format takes type json_object or json_schema. We check a json_schema before the request runs: one we cannot use is answered with a 400 before any token is generated. We also check every answer that is not streamed: if it is not valid JSON, or does not match your schema, you get 502 invalid_output instead, and nothing is billed (output_check_failed when the check could not finish in time). An answer cut off by max_tokens comes back as it is, with finish_reason length. Streamed answers are not checked. No model in this release declares structured outputs.

Log probabilities

logprobs and top_logprobs are passed to the model, and what it returns comes back in each choice’s logprobs. No model in this release declares them.

Text completions

curl
curl https://api.peryn.ai/v1/completions \-H "Authorization: Bearer $PERYN_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "llama-3.1-8b-instruct", "prompt": "The capital of France is", "max_tokens": 16}'

Response headers

  • x-request-id and Inference-Id on every response: answers, errors and streams alike, including a 503 while the gateway restarts. Both carry the same value, starting with req_. It is the id your request, its token counts and its cost are recorded under.
  • x-pc-node-country on every response a GPU node served, streamed or not: the node’s country as a two-letter code (ISO 3166-1).

Keep the request id with your own logs, and quote it when you write to us about a request. We store no prompts or answers, so the id is how we find it. On an error, the OpenAI SDKs give it as request_id (Python) and requestID (JavaScript); the sample under Ошибки prints it.

curl
curl -sS -D - -o /dev/null https://api.peryn.ai/v1/chat/completions \-H "Authorization: Bearer $PERYN_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "llama-3.1-8b-instruct", "max_tokens": 8, "messages": [{"role": "user", "content": "Hi"}]}'

Streaming#

Server-sent events in the OpenAI format: tokens arrive as the model writes them.

Set stream: true. Each event is a data: line with a chat.completion.chunk; the text is in choices[0].delta.content and a final chunk carries finish_reason. With stream_options: {"include_usage": true} every chunk has "usage": null and one more chunk, with empty choices, carries the token counts. The stream ends with data: [DONE].

curl -N https://api.peryn.ai/v1/chat/completions \-H "Authorization: Bearer $PERYN_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "llama-3.1-8b-instruct","max_tokens": 128,"stream": true,"stream_options": {"include_usage": true},"messages": [{"role": "user", "content": "Write a haiku about GPUs."}]}'

On the wire (abridged)

: ping
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","created":1791216000,"model":"llama-3.1-8b-instruct","choices":[{"index":0,"delta":{"role":"assistant","content":"Silicon"},"logprobs":null,"finish_reason":null}],"usage":null}
data: {…,"choices":[{"index":0,"delta":{"content":" hums"},"logprobs":null,"finish_reason":null}],"usage":null}
data: {…,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null}
data: {…,"choices":[],"usage":{"prompt_tokens":16,"completion_tokens":19,"total_tokens":35}}
data: [DONE]
After the first chunk, … stands for the same id, object, created and model.
  • Lines that start with a colon (: ping) keep the connection open while the model works on its first token. The OpenAI SDKs skip them.
  • An error before the first event comes back as a normal HTTP error. An error after the stream has started arrives as an event: error line with the error JSON, then data: [DONE].
  • If the stream breaks or you close it, you pay for the tokens that reached you and nothing more. If none did, you pay nothing.
  • If no GPU is serving the model, a streamed request waits too, and sends nothing until a GPU takes it (see When GPUs are busy).

Models and prices#

Live prices in US dollars per million tokens, excluding VAT.

Put the model id in the model field. These are our Standard prices, per model, 30% below market. They can change; a request pays the price in force when it starts.

  • llama-3.1-8b-instructAvailable

    Llama 3.1 8B Instruct · 8B · 32,768 tokens, max output 8,192

    Input
    $0.014
    Output
    $0.028

The same table is JSON at https://app.peryn.ai/api/pricing and, with context lengths, at GET /v1/catalog. The same prices are on the pricing page; every model’s licence is on the licences page.

curl
curl https://api.peryn.ai/v1/catalog

What a request costs

Input tokens times the input price plus output tokens times the output price, rounded up to the next millionth of a dollar. We count the tokens ourselves with the model’s own tokenizer; the counts are the usage in every answer and on your usage page.

Privacy tiers#

New keys use the Standard tier. Private is on request: talk to us.

Standard: the GPU node answers, on a GPU that also mines $PEARL.
Private, on request: vetted nodes only, never mined.

Standard

No training on prompts or completions, ever. Zero retention: we do not log or store prompt or completion content; we keep only request metadata (such as request ID, account, timestamps, model, token counts, latency, cost and status) for billing and reliability. Standard runs on GPUs that also mine $PEARL; Mining and your data in the privacy policy explains what that means. The prices above are Standard prices.

Where your requests run

By default, a request runs on any healthy node, in any country. Set a region rule for your whole account under Настройки. Narrow it for one key on the API keys page. A rule is EU only, US only, US + EU, your own list of countries, or countries to exclude. Requests then run only on nodes in the allowed countries. If those nodes are all busy, the request gets 429 no_capacity. If none of them serves the model, it is held as described under When GPUs are busy, then fails with 503 and code no_capacity_in_region. It never runs elsewhere instead.

A node’s country comes from its operator’s declaration, checked against the location of its IP address. A dishonest operator could fake both (for example with a VPN); we remove nodes we catch. Each answer names its node’s country in x-pc-node-country, and your usage page breaks your requests down by country.

Rate limits and credits#

Per-key limits per minute, and prepaid credit in US dollars.

Prepaid credit

  • Held while a request runs: its worst case
  • Charged when it ends: the tokens it used
  • The rest of the hold goes back to your credit

Limits per key

  • 60 requests per minute
  • 200,000 tokens per minute

Rate limits

  • Each key allows 60 requests and 200,000 tokens per minute. Both refill continuously. The API keys page shows each key’s limits. Need more? Talk to us.
  • A request counts its input tokens plus max_tokens against the token limit when it starts. When it ends, it gets back what it didn’t use. Without max_tokens it counts the model’s full output allowance (up to 8,192 tokens), so setting it lets more requests run.
  • Over a limit, the request is refused at once with 429, code rate_limit_exceeded, and a Retry-After header in seconds. Nothing is queued; wait that long and retry.
  • When every GPU for a model is busy, the request is refused at once with 429, code no_capacity, and a Retry-After header, rather than waiting in a queue.

Credits

  • Credit is prepaid in US dollars, excluding VAT. Pay with stablecoins: your account’s own deposit address on Base, Arbitrum or Ethereum is under Add credits, with the token to send, once you accept the customer terms. A deposit is credited dollar for dollar once its block is final. Deposits under $1 are held until your held deposits reach $1. Send only that token, on those networks: anything else is not credited automatically.
  • When a request starts we hold its worst case: input tokens plus max_tokens at the model’s price. When it ends we charge what it used and release the rest. If your available credit can’t cover the hold, the request is refused with 402, code insufficient_quota.
  • A request that fails before any token reaches you costs nothing.
  • The usage page shows requests, tokens and cost per key, model and country, for the last 7, 30 or 90 days.
  • Unused credit expires after 12 months without activity (a sign-in, a request or a purchase). We email you at least 30 days before.

Ошибки#

Errors use the OpenAI shape, so the OpenAI SDKs raise them as exceptions with the status code.

Error body

HTTP/1.1 404 Not Found

{
"error": {
"message": "The model 'no-such-model' does not exist or is not available.",Written for people. Log it or show it.
"type": "invalid_request_error",The kind of error.
"param": "model",The field at fault, when there is one.
"code": "model_not_found"Stable. Branch on it.
}
}

Errors that can clear by themselves (429, 503) carry a Retry-After header.

400invalid_request_error
invalid_jsoninvalid_valueinvalid_messagesinvalid_response_formatcontext_length_exceededprompt_too_complexunsupported_parameterunsupported_valueunsupported_contentbad_requesttier_unavailableThe request needs fixing. The body is not a JSON object, a field is out of range, the messages do not fit the model’s chat format, the response_format or its JSON Schema cannot be used, or prompt plus max_tokens is over the context. Other causes: a feature the API does not take, a request the gateway could not read (a malformed URL, or a Content-Length that does not match the body) or the model refused (bad_request; a refusal gives the model’s reason), or a prompt that took more than 5 seconds to tokenize (very long runs of letters or symbols without spaces). tier_unavailable: the privacy tier you asked for is on request for this model. param names the field. Retrying unchanged gives the same answer.
401authentication_error
missing_api_keyinvalid_api_keyrevoked_api_keyNo key, a key we do not know (or a malformed Authorization header), or a revoked key.
402insufficient_quota
insufficient_quotaYour available credit does not cover this request’s hold. Lower max_tokens, or get more credit (see Rate limits and credits).
403permission_error
account_disabledThe account is disabled. Write to us.
404invalid_request_error
model_not_foundnot_foundUnknown model id, or a path the API does not have.
413invalid_request_error
request_too_largeThe body is larger than 2 MB.
415invalid_request_error
unsupported_media_typeThe Content-Type header could not be read. Send the body with Content-Type: application/json.
429rate_limit_error
rate_limit_exceededno_capacityrate_limit_exceeded: your key’s requests or tokens per minute are used up, or your account’s share of time for counting tokens or for compiling JSON Schemas and checking answers against them (while that share is used up, a non-streaming request with a json_schema is refused before it runs). no_capacity: every GPU serving this model is busy right now. Wait for Retry-After, then retry.
500server_error
internal_errorregion_rule_invalidSomething failed on our side. Retry with backoff. region_rule_invalid: save your region rule again in the console.
502server_error
upstream_errorinvalid_outputoutput_check_failedupstream_error: the GPU node serving the request failed. invalid_output: the answer was not valid JSON or did not match your schema. output_check_failed: the answer could not be checked against your schema in time. Neither of the last two is billed. Retry.
503server_error
no_capacityno_capacity_in_regiontokenizer_unavailableschema_check_unavailableshutting_downgateway_read_onlyspool_unavailableno_capacity: no GPU is serving this model (see When GPUs are busy, under Models and prices). no_capacity_in_region: none in the countries your region rule allows. tokenizer_unavailable or schema_check_unavailable: the prompt could not be counted, or your JSON Schema checked, right now. shutting_down: the gateway is restarting. gateway_read_only or spool_unavailable: the API runs on its standby for a few minutes; inference goes on, but batches and files wait. Retry after Retry-After.
504server_error
timeoutThe model did not finish within 5 minutes. Retry, or lower max_tokens.
400invalid_request_error
invalid_multipartmissing_fileempty_fileinvalid_fileBatch API uploads (POST /v1/files): the body is not multipart/form-data with purpose=batch and a file, the file is missing or empty, or it is not UTF-8 text (JSONL).
403permission_error
batch_not_allowedbatch_not_availableBatch API: batch_not_allowed: this key cannot use it (use a Standard key from the console). batch_not_available: batches are not open to your account.
409invalid_request_error
file_in_usebatch_endedBatch API: file_in_use: a running batch reads this file; cancel the batch first. batch_ended: the batch has already ended.
413invalid_request_error
file_too_largeBatch API: the file is larger than a batch file may be (the message gives the limit).
429rate_limit_error
file_limitbatch_limitBatch API: file_limit: you keep too many files; delete some. batch_limit: too many of your batches are running; wait for one to finish.
curl -i https://api.peryn.ai/v1/chat/completions \-H "Authorization: Bearer $PERYN_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "no-such-model", "messages": [{"role": "user", "content": "Hi"}]}'

Retry 429, 500, 502, 503 and 504 with backoff; the OpenAI SDKs do this for you (twice by default). Fix the request for the other codes. Stuck? Write to hello@peryn.ai with the request id from x-request-id or Inference-Id.

Майнинг с Peryn#

Mine Pearl through our pool.

Set up your machine

Run our agent on any Linux machine with an NVIDIA GPU. No account: the $PEARL address in the command is where we pay.

Одна команда
curl -fsSL https://peryn.ai/install | sh -s -- YOUR_PEARL_ADDRESS
  • It asks for sudo, installs our agent as a service, and updates itself.
  • Needs NVIDIA driver 580 or newer for Blackwell datacenter, RTX PRO and RTX 50; 570 or newer for Hopper; 550 or newer for RTX 40, RTX 30, RTX Ada, Ada datacenter, RTX Ampere, Ampere datacenter and Turing.
  • On HiveOS, a flight sheet runs our agent on every rig: Mine with HiveOS. HiveOS ships NVIDIA driver 550, which can’t run RTX 50 or RTX PRO Blackwell cards. On those rigs, update to 580 or newer first: nvidia-driver-update 580.178.04 && reboot.
  • To join an account instead, put a fleet key from the miner portal in place of the address.

Нужен кошелёк? → Pearl Safe (откроется в новой вкладке)

Выплаты

  • Условия — в правилах нашего пула.
  • A block reward is credited after 100 confirmations. A block that leaves the chain before that pays nothing, and its credit is removed.
  • Выплата на ваш адрес $PEARL (каждые 2 часа), когда начислено от 1 $PEARL. Less stays owed and is paid in a later batch; nothing is lost.
  • Every payout is screened against sanctions lists before it is sent.

Fees and payout schemes

PPS+
1%
A fixed payment for every share, plus transaction fees. No luck involved. The default.
PPLNS
1%
Paid from the blocks the pool finds. Choose it with mode=pplns in the rig’s password.
Founding Miners
0% PPLNS / 0.5% PPS+
0% on PPLNS until Pearl’s FP8 upgrade and for 6 months after it.

GPU Clouds accounts pay the Duplex fee: 2% of the $PEARL their enrolled machines mine, in place of the pool fee, and no other fees. It doesn’t stack with the Founding Miner terms: their other mining keeps the Founding rate.

With PPLNS, when the pool finds a block, the whole reward is split among the shares in the last stretch of work: the latest accepted shares whose difficulty adds up to twice the network difficulty. Your part is your shares’ difficulty in that stretch. A share counts towards every block found while it is in the stretch, so steady mining is paid steadily, and joining only when the pool looks lucky gains nothing.

Your dashboard

Look up your $PEARL address to see its hashrate, accepted and rejected shares, $PEARL estimated, owed and paid, and each worker. No sign-in. Look up your address.

Нужен кошелёк? → Pearl Safe (откроется в новой вкладке)

Running a fleet? Tell us about your fleet. See the network mine and serve on peryn.ai/live.

Troubleshooting

Rejected shares show on your dashboard by reason. What each one means:

21 Stale share (job expired: new block)
Новый блок пришёл раньше, чем шара дошла до пула. Несколько на сотню — норма. Больше — признак медленной связи: используйте ближайший к вам TLS-порт или проводное подключение.
21 Stale share (job not found)
Шара относилась к заданию, которое это подключение не получало или которое давно заменено. Перезапустите майнер, чтобы он взял свежие задания. Если повторяется, проверьте, что подключение использует только один процесс майнера.
22 Duplicate share
Одно и то же доказательство отправлено дважды. Обычно это повтор майнера после потерянного ответа. Проверьте сеть между ригом и пулом.
22 Duplicate share (already credited, sent again in other bytes)
Уже засчитанная пулом шара отправлена повторно в другой кодировке. Честный повтор отправляет те же байты. Обновите майнер: такие шары учитываются для бана.
23 Low difficulty share
Сложность шары ниже той, что запросил пул. Уберите d=N из пароля или увеличьте значение. Обновите майнер, если он игнорирует сложность задания.
23 Low difficulty share (rank penalty)
Шара прошла обычный таргет, но не штраф Pearl за её ранг шума. Обновите майнер до версии, которая учитывает штраф за ранг. Такие отклонения никогда не ведут к бану.
20 Invalid proof
Верификатор Pearl отклонил доказательство. Часто это нестабильный разгон или ошибки памяти. Снизьте частоты, обновите драйвер, затем майнер.
20 Invalid proof: decode
Не удалось прочитать доказательство. Обновите майнер. Проверьте, что он настроен на Pearl.
20 Invalid proof: rank
Доказательство использует ранг шума, который сеть не принимает. Используйте настройки майнера для Pearl по умолчанию.
24 Unauthorized worker (banned)
Это подключение отправило слишком много невалидных шар и временно приостановлено. Устраните причину невалидных шар; пауза закончится сама.

Using WildRig? Its pearlhash mode only works with pearlhash.xyz. On Peryn Pool use MH-Miner, SRBMiner, BzMiner, OneZeroMiner or Peryn’s own miner.

For GPU owners#

Your GPU can serve these requests and mine $PEARL.

At launch, nodes mine only: no AI requests, no 50 GB disk check and no model downloads. The serving steps below apply once serving opens.

Your GPU mines $PEARL through our pool and serves requests. Our miner image runs the model and our node software, which never logs or stores prompts or completions. Running a fleet? Tell us about your fleet.

What you need

  • An NVIDIA Hopper or Blackwell GPU (x86_64 or arm64).
  • NVIDIA driver r580 or newer (CUDA 13).
  • A container with 16 GB of shared memory, and disk for our image and the model weights.
  • Outbound HTTPS and WebSocket only. No inbound ports: the node dials out to us.

Connect a node

  1. Sign in to the miner portal and choose Add a node. Give it a name, its country and a model. You get an enrolment token: single use, valid for 24 hours.
  2. Run the command the portal shows, with the image reference we send you, on RunPod, Vast.ai or your own server. The node enrols and connects to our gateway and our pool. Ask us for the image reference: tell us about your fleet.
  3. The node mines from the start. Customer requests start once we approve it: we check who you are, its test requests and its country.
  4. Add your payout address under Выплаты: a $PEARL address on Pearl. $PEARL you earn stays owed until you add one.

    Нужен кошелёк? → Pearl Safe (откроется в новой вкладке)

To mine without serving API requests, tick Pool only (no API traffic) when you create the token. The node then earns $PEARL only and needs no approval.

Условия — в правилах нашего пула. A block reward counts after 100 confirmations. The payout rules are under Выплаты; $PEARL estimates are on the GPU clouds page.

Pool API#

Public JSON for pool-listing sites: the pool, its blocks, its payments and one address.

Base URL: https://app.peryn.ai/api/v1. GET only, no key, from any origin. Every answer carries "v": 1.

Amounts are $PEARL as strings with 8 decimals ("2.50000000"), hashrates are numbers in MAC/s (the unit field), and times are ISO 8601 in UTC.

Caching and limits

Answers may be cached for 60 seconds (Cache-Control: public, max-age=60); the server computes each one at most once a minute. Up to 60 requests a minute per IP address, then 429 with Retry-After. /miner/{address} shares the address dashboard’s limit (60 a minute per network) and is recomputed at most every 15 seconds per address.

GET /api/v1/pool

The pool: fees, payouts, stratum hosts, pool and network numbers.

name, coin, algorithm
The pool, PEARL and pearlhash.
fees.pplns, fees.fpps
Each scheme’s open flag and fee in percent. fpps is PPS+; its fee is null while it is not open.
fees.founding
The Founding Miners rule, in one sentence.
payouts
The minimum payout, the payout schedule and the confirmations before a block reward counts.
stratum[]
Each listed region: id, label, location, host, TCP and TLS ports, and status (up, degraded, down or unknown).
pool.hashrate10m, pool.hashrate24h
The pool’s hashrate over the last 10 minutes and the last 24 hours.
pool.miners, pool.workers
Workers with an accepted share in the last 10 minutes (Miners connected on the live page), and in the last hour.
pool.blocksFound, pool.lastBlock
Blocks found, and the latest one’s height and time.
networkStats
The network’s hashrate, difficulty and height; null when unknown.
Example
{"v": 1,"name": "Peryn Pool","coin": "PRL","algorithm": "pearlhash","network": "mainnet","unit": "MAC/s","fees": {"pplns": {"open": true,"feePct": 1},"fpps": {"open": true,"feePct": 1},"founding": "Founding Miners Season 1: 0% on PPLNS until Pearl’s FP8 upgrade and for 6 months after it; 0.5% on PPS+."},"payouts": {"minimumPrl": "1.00000000","schedule": "every 2 hours","coinbaseMaturityBlocks": 100},"stratum": [{"region": "eu","label": "Europe","location": "Frankfurt","host": "pool.peryn.ai","tcpPort": 3333,"tlsPort": 3443,"status": "up"}],"pool": {"hashrate10m": 59000000000000000,"hashrate24h": 56000000000000000,"miners": 165,"workers": 180,"blocksFound": 412,"lastBlock": {"height": 131204,"time": "2026-11-02T12:00:00.000Z"}},"networkStats": {"hashrate": 410000000000000000,"difficulty": 12000000,"height": 131260},"updatedAt": "2026-11-02T12:00:00.000Z"}

GET /api/v1/blocks

The blocks the pool found.

blocks[]
height, hash, time, rewardPrl, status (submitted, pending, mature or orphaned) and confirmations. Newest first, at most 50.
Example
{"v": 1,"network": "mainnet","blocks": [{"height": 131204,"hash": "a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1","time": "2026-11-02T12:00:00.000Z","rewardPrl": "50.00000000","status": "pending","confirmations": 56}],"updatedAt": "2026-11-02T12:00:00.000Z"}

GET /api/v1/payments

The pool’s payout batches.

before
An ISO 8601 time in UTC: only payments sent before it. Pass the previous page’s next to get the page after it. Anything else answers 400 with invalid_cursor.
limit
How many payments, 1 to 50 (50 when left out). A larger number counts as 50, a smaller one as 1.
payments[]
time, totalPrl, payees (how many addresses were paid), txids, and networkFeePrl: the transaction’s network fee, paid by the pool (networkFeePaidBy), never taken from a payout; null until it confirms. Newest first, at most 50. No payee is listed.
next
The time of this page’s last payment: the before of the next page. null on the last page.
Example
{"v": 1,"network": "mainnet","payments": [{"time": "2026-11-02T12:00:00.000Z","totalPrl": "1834.25000000","payees": 96,"txids": ["3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f"],"networkFeePrl": "0.00042250","networkFeePaidBy": "pool"}],"next": null,"updatedAt": "2026-11-02T12:00:00.000Z"}

GET /api/v1/miner/{address}

One $PEARL address: hashrate, workers, balance and payouts.

A $PEARL address on this network; anything else answers 400 with invalid_address.

limit
Pages the workers: how many, 1 to 1,000 (1,000 when left out), online first, then by name. Without limit, after or status the answer lists the first 1,000 workers, online first.
after
The previous page’s next: the workers after it. Anything else answers 400 with invalid_cursor.
status
online: online workers only. Anything else answers 400 with invalid_status.
hashrate1h, hashrate24h
The address’s hashrate over the last hour and the last 24 hours.
workersOnline, workersOffline
A worker is online with an accepted share in the last 6 minutes.
workers[]
name, label (its machine’s label, null when none), online, hashrate1h, hashrate24h and lastShare per worker.
balance
owedPrl (matured, not paid yet), pendingPrl (in blocks not yet mature) and paidPrl.
payouts[]
time, amountPrl, status and txids, newest first.
next
With limit, after or status: the after of the next page of workers. null on the last page.
Example
{"v": 1,"address": "prl1p…","network": "mainnet","unit": "MAC/s","hashrate1h": 310000000000000,"hashrate24h": 290000000000000,"workersOnline": 1,"workersOffline": 0,"workers": [{"name": "rig01","online": true,"hashrate1h": 310000000000000,"hashrate24h": 290000000000000,"lastShare": "2026-11-02T12:00:00.000Z"}],"balance": {"owedPrl": "0.42000000","pendingPrl": "3.10000000","paidPrl": "25.00000000"},"payouts": [{"time": "2026-11-02T12:00:00.000Z","amountPrl": "2.50000000","status": "sent","txids": ["3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f"]}],"updatedAt": "2026-11-02T12:00:00.000Z"}