Heartank®Developersអ្នកអភិវឌ្ឍន៍Log inចូល

Thank with HeartBank®

Record a thank on the gratitude ledger. Your app never writes a thank alone: the person signs it with their own passkey.កត់ត្រាការអរគុណក្នុងបញ្ជីនៃការដឹងគុណ។ កម្មវិធីរបស់អ្នកមិនដែលសរសេរការអរគុណតែឯងទេ៖ មនុស្សនោះចុះហត្ថលេខាវាដោយ passkey ផ្ទាល់ខ្លួន។

1 Prepare១ រៀបចំ
Your server asks the ledger. It answers with a ticket.ម៉ាស៊ីនមេរបស់អ្នកសួរបញ្ជី។ វាឆ្លើយដោយសំបុត្រមួយ។
2 The person presses២ មនុស្សនោះចុច
They open sign.333.eco, which shows them what they are signing, and press their passkey.ពួកគេបើក sign.333.eco ដែលបង្ហាញពួកគេនូវអ្វីដែលពួកគេកំពុងចុះហត្ថលេខា ហើយចុច passkey របស់ពួកគេ។
3 Commit៣ បញ្ជូន
Your server sends the press back. The ledger writes the thank and gives you a receipt.ម៉ាស៊ីនមេរបស់អ្នកផ្ញើការចុចត្រឡប់មកវិញ។ បញ្ជីសរសេរការអរគុណ ហើយផ្តល់បង្កាន់ដៃឱ្យអ្នក។
const { pending, ticket } = await ledger.prepare({ ref, ledger: "kiitos", to })
// the person presses at sign.333.eco/press#ticket=…
const { receipt } = await ledger.commit({ ref, pending, pressToken })

Outside apps: from season 2កម្មវិធីខាងក្រៅ៖ ចាប់ពីរដូវកាលទី ២

Apps outside HeartBank® write from 7 January 2027, after review.កម្មវិធីក្រៅពី HeartBank® សរសេរចាប់ពីថ្ងៃទី ៧ ខែមករា ឆ្នាំ ២០២៧ បន្ទាប់ពីការពិនិត្យ។

Kiitos, and Kiitti as thanks to all of lifeKiitos និង Kiitti ជាការអរគុណចំពោះជីវិតទាំងអស់

An outside app writes Kiitos, and Kiitti only as a person's thanks to all of life. Care for a plant or an animal is witnessed, never claimed by an app.កម្មវិធីខាងក្រៅសរសេរ Kiitos ហើយ Kiitti តែជាការអរគុណរបស់មនុស្សចំពោះជីវិតទាំងអស់ប៉ុណ្ណោះ។ ការថែទាំរុក្ខជាតិ ឬសត្វ ត្រូវបានធ្វើជាសាក្សី មិនដែលអះអាងដោយកម្មវិធីទេ។

A refusal says nothingការបដិសេធមិននិយាយអ្វីទេ

When the ledger declines a thank, your app is told only that it wasn't written. No reason and no count: it protects the people involved. It is not a bug.នៅពេលបញ្ជីបដិសេធការអរគុណ កម្មវិធីរបស់អ្នកត្រូវបានប្រាប់តែថាវាមិនត្រូវបានសរសេរ។ គ្មានហេតុផល គ្មានចំនួន៖ វាការពារមនុស្សដែលពាក់ព័ន្ធ។ វាមិនមែនជាកំហុសទេ។

ឯកសារយោងខាងក្រោមមានជាភាសាអង់គ្លេសតែប៉ុណ្ណោះ។

Thank with HeartBank®: reference

Record a thank on the gratitude ledger. Your app prepares it, the person presses their own passkey, your app commits it.

The gratitude ledger's API (repo H3/heartbank.net/ledger.heartbank.net, src/http.ts). ⭐ An agent can do everything except the press: every thank is signed by the person's own passkey at sign.333.eco, so no app and no agent can write a thank alone.

⚠️ First-party apps only today. Outside apps write from season 2 (7 January 2027), after review, and then Kiitos, and Kiitti only as a person's thanks to all of life (directive #94).

⚠️ A refusal says nothing: when the ledger declines a thank, the answer is only {"written": false}, with no reason and no count. It protects the people involved; it is not a bug.

The flow: (1) POST /v1/prepare → {pending, ticket}. (2) Send the person's browser to https://sign.333.eco/press#ticket=…&return_to=…&state=…; the page shows them what they are signing, and they press. The browser comes back to your return_to with #press=…&state=…. (3) Your server exchanges that result at POST https://login.333.eco/press/wrap (form field result) for a pressToken. (4) POST /v1/commit → the receipt's id.

POST https://ledger.heartbank.net/v1/prepare

Step 1: prepare a thank

Runs the rule. If it would write, builds the thank and returns a ticket for the person's press. At most 6 prepares a minute per person.

Who may call it: Your app's server proves itself with a fresh ES256 JWT (private_key_jwt): iss = sub = your client id, aud = https://ledger.heartbank.net, at most 5 minutes old, with a jti never used before. ⚠️ Its own header, not Authorization: Cloud Run reads Authorization: Bearer as a Google token. ⛔ Never sent from a browser or a phone.

Body application/json

One of: { ref, pidToken, sub, ledger, to, cargo }

FieldTypeWhat it is
refstringYour id for this thank. The same ref returns the same answer and writes once.
pidTokenstring
substring
ledger"kiitos"
to{ pidToken, sub }⏳ Outside apps will name the receiver by registry handle instead, never another person's token (A591 (3)).
cargo optionalstringOptional: exactly 32 bytes of your own, committed with a salt (never stored as sent); it reaches the two people in their records.

Or: { ref, pidToken, sub, ledger, dir, evidence }

First-party only (B-Twin, thank.333.eco): care for a thing, plant or animal, decided by the ledger's public rule on witnessed evidence. ⛔ Never an outside app: from season 2 an outside app's Kiitti is only a person's thanks to all of life, a call with no direction, twin or evidence field (directive #94).

FieldTypeWhat it is
refstring
pidTokenstring
substring
ledger"kiitti"
dir"kind" | "thankful"
evidence{ kind, twinId, attested, match }

Answers

  • 200 A ticket, or not written. object or object
  • 400 Refused (a bad assertion, an app not admitted, an app whose writing is paused, a malformed body). { error }
  • 403 Refused (a bad assertion, an app not admitted, an app whose writing is paused, a malformed body). { error }
  • 503 The ledger is unavailable; try again. { error }

On the MCP server: not a tool: ⛔ no tool can write a real thank (SPEC §6.1)

POST https://ledger.heartbank.net/v1/commit

Step 3: commit the pressed thank

The ledger checks the press itself, against exactly what its zero-sum proof can hold. Safe to retry: the answer is kept under ref.

Who may call it: Your app's server proves itself with a fresh ES256 JWT (private_key_jwt): iss = sub = your client id, aud = https://ledger.heartbank.net, at most 5 minutes old, with a jti never used before. ⚠️ Its own header, not Authorization: Cloud Run reads Authorization: Bearer as a Google token. ⛔ Never sent from a browser or a phone.

Body application/json

FieldTypeWhat it is
refstring
pendingstring
pressTokenstringFrom POST https://login.333.eco/press/wrap.

Answers

  • 200 Written, or not. object or object
  • 400 Refused (a bad assertion, an app not admitted, an app whose writing is paused, a malformed body). { error }
  • 403 Refused (a bad assertion, an app not admitted, an app whose writing is paused, a malformed body). { error }
  • 503 The ledger is unavailable; try again. { error }

On the MCP server: not a tool: ⛔ no tool can write a real thank, and none can press (SPEC §6.1)

POST https://ledger.heartbank.net/v1/place

Place one side of a written thank on the public map

A cell number and a one-use token, and nothing else: there is no field for a coordinate. Call it later than the thank, so a placing's time does not point at a thank.

Who may call it: Your app's server proves itself with a fresh ES256 JWT (private_key_jwt): iss = sub = your client id, aud = https://ledger.heartbank.net, at most 5 minutes old, with a jti never used before. ⚠️ Its own header, not Authorization: Cloud Run reads Authorization: Bearer as a Google token. ⛔ Never sent from a browser or a phone.

Body application/json

FieldTypeWhat it is
tokenstring
cellintegerAn area about 100 km across (0.9° bands), from the ledger's open cell function.

Answers

  • 200 Placed, or not. { placed }
  • 400 Refused (a bad assertion, an app not admitted, an app whose writing is paused, a malformed body). { error }
  • 403 Refused (a bad assertion, an app not admitted, an app whose writing is paused, a malformed body). { error }
  • 503 The ledger is unavailable; try again. { error }

What a success answer holds

FieldTypeWhat it is
placedboolean

On the MCP server: not a tool: ⛔ no tool can write a real thank (SPEC §6.1)

GET https://ledger.heartbank.net/v1/aura

Read a person's ring

A color and a width per ledger this app may read, for the logged-in person. ⛔ No balance, no count: a ring, never a number to chase.

Who may call it: Your app's server proves itself with a fresh ES256 JWT (private_key_jwt): iss = sub = your client id, aud = https://ledger.heartbank.net, at most 5 minutes old, with a jti never used before. ⚠️ Its own header, not Authorization: Cloud Run reads Authorization: Bearer as a Google token. ⛔ Never sent from a browser or a phone.

Parameters

NameTypeWhat it is
sub (query)string
x-pid-token (header)string

Answers

  • 200 The rings this app may read. { kiitos, kiitti }
  • 403 Refused (a bad assertion, an app not admitted, an app whose writing is paused, a malformed body). { error }
  • 503 The ledger is unavailable; try again. { error }

What a success answer holds

FieldTypeWhat it is
kiitos optional{ color, ring }
kiitti optional{ color, ring }

On the MCP server: not a tool: needs a person's token; ⛔ an agent never holds one

POST https://ledger.heartbank.net/v1/submit

Retired: a thank without a press (retired)

The test tree's season 0 only. From season 1 every thank needs the person's press, and this answers 403 (founder 2026-11-09).

Who may call it: Your app's server proves itself with a fresh ES256 JWT (private_key_jwt): iss = sub = your client id, aud = https://ledger.heartbank.net, at most 5 minutes old, with a jti never used before. ⚠️ Its own header, not Authorization: Cloud Run reads Authorization: Bearer as a Google token. ⛔ Never sent from a browser or a phone.

Answers

  • 403 Refused (a bad assertion, an app not admitted, an app whose writing is paused, a malformed body). { error }

On the MCP server: not a tool: retired