An external bot uses a personal API key to call the same JSON API a signed-in person uses. Create the key on your profile. Read OpenAPI or the plain-text guide if you are a language model.
How a bot authenticates
Send one of these headers on every call:
Authorization: Bearer rk_…
X-Api-Key: rk_…
The secret starts with rk_. It is shown once, with a copy button, and cannot be shown again. The Node stores only a SHA-256 hash. The email does not contain the API key.
Identifiers
Path parameters named id, partyId, requestId, methodId, and electionId are UUIDs. A sequential integer is rejected with 400 and ID_NOT_UUID, so the path does not reveal how many people or records exist. The on-chain election id stays inside the election object for the circuit. Short links /v/{code} and /e/{code} redirect to /vote/{uuid} and are not accepted as /api/elections/:id.
Ballot labels (questionId, optionId), guardian slots (:index), mail template names, and page slugs are not record counts. A new jurisdiction is assigned a UUID.
curl -sS \
-H "Authorization: Bearer $REPUBLIC_API_KEY" \
-H "Accept: application/json" \
"$ORIGIN/api/me"
Authorization levels
One account can hold many keys. Each key has its own level. The level is a ceiling. The person’s existing role is still enforced.
read— Read-only. GET and HEAD, plus receipt and outcome verification. Cannot create, vote, register, email, or change a profile.voter— Voter. Read-only plus this person’s own actions: contact email, vote PIN, registration request, ballot submit, identity methods, notifications, feedback, and outcome subscriptions.officer— Officer. Voter plus the clerk, registrar, disqualification officer, tally operator, election staff, and platform admin routes this account is already allowed to call. A key does not add a role the person does not hold.
Expiration
Choose one expiration when you create the key. The default is 30d.
7d30d90d180d365dnever
After expiresAt, the key is rejected. never does not expire. Revoke a key from the profile, or with DELETE /api/me/api-keys/:id using a voter or officer key. Revocation takes effect immediately.
Create a key
Sign in, open /me, and use API keys. The browser session calls:
POST /api/me/api-keys
Content-Type: application/json
{ "name": "assistant", "level": "read", "expiresIn": "30d" }
level is read, voter, officer. An API key cannot create another key.
Creating a key sends the email template api_key.created to the account contact email (or the primary email). The message says an API key was created and does not include the key. If you did not create it, contact support as soon as possible at /feedback, then revoke the key.
Errors
JSON errors use { "error": "…", "nfp": true, "code": "…" }. 401 means the key is missing, unknown, revoked, or expired. 403 with API_KEY_SCOPE means this key’s level cannot make that call. Ballot choice is never a response field.
Route groups
A route that is not listed here rejects a personal API key. Sign-in routes are listed so a bot can complete email or Ethereum login, and they refuse an API key so a key cannot mint a browser session.
Status
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/health |
read | No | Process health, writer mode, chain id, and the hourly disclosure window. |
GET |
/api/health |
read | No | Same payload as GET /health. |
GET |
/api/config |
read | No | Public Node configuration: voting hostname, chain, polls flag, identity caps, ballot types, receipt portal, and outcome portal. |
Documentation
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api |
read | No | Human documentation for this bot API. Send Accept: application/json, or ?format=json, for a machine index of the same routes. |
GET |
/api/openapi.json |
read | No | OpenAPI 3 description of every route listed here. |
GET |
/api/llms.txt |
read | No | Plain-text guide for a language model that will call this API. |
GET |
/llms.txt |
read | No | Same plain-text guide as GET /api/llms.txt. |
Sign-in
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
POST |
/api/auth/passkey/register/begin |
session | No | Begin WebAuthn registration. An API key is refused here. A bot that already has a key does not need this ceremony. Body: handle, acceptedTerms. |
POST |
/api/auth/passkey/register/finish |
session | No | Finish WebAuthn registration and start email MFA when MFA is on. Body: WebAuthn credential, handle, email. |
POST |
/api/auth/passkey/login/begin |
session | No | Begin WebAuthn sign-in. Body: handle. |
POST |
/api/auth/passkey/login/finish |
session | No | Finish WebAuthn sign-in. Sets the session cookie after MFA. |
POST |
/api/auth/web3/challenge |
session | No | Issue a sign-in challenge for a bound Ethereum address. Body: address. |
POST |
/api/auth/web3/login |
session | No | Submit the Ethereum signature for that challenge. Body: address, signature. |
POST |
/api/auth/email/start |
session | No | Start email sign-in. The one-time code arrives by transactional email. Body: email. |
POST |
/api/auth/smart-card/challenge |
session | No | Issue a smart-card sign-in challenge. |
POST |
/api/auth/smart-card/login |
session | No | Complete smart-card sign-in. |
POST |
/api/auth/civic-id/login |
session | No | Sign in with a hashed driver license or passport already bound to the person. |
GET |
/api/auth/mfa/status |
session | No | Whether email MFA is required and whether SES is configured. |
POST |
/api/auth/mfa/email |
session | No | Send or confirm the email factor during sign-in. |
POST |
/api/auth/mfa/resend |
session | No | Resend the email one-time code. |
POST |
/api/auth/mfa/verify |
session | No | Verify the email one-time code and receive the session cookie. Body: code. |
POST |
/api/auth/logout |
session | Yes | End the browser session. An API key is refused here. |
GET |
/api/auth/session |
session | Yes | Session cookie profile. Prefer GET /api/me with an API key. |
Profile
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/me |
read | Yes | The signed-in person: handle, role, identity summary, jurisdiction grants, and election registration status. Choice is never included. |
GET |
/api/session |
read | Yes | Same payload as GET /api/me. |
PATCH |
/api/me/contact-email |
voter | Yes | Set or clear the contact email used for operator notices and the API-key alert. Body: contactEmail. |
GET |
/api/notifications |
read | Yes | In-app notices for this person, newest first. |
POST |
/api/notifications/:id/read |
voter | Yes | Mark one notice read. |
API keys
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/me/api-keys |
read | Yes | List this account’s API keys. The secret is never returned. Revoked and expired keys stay in the list. |
POST |
/api/me/api-keys |
session | Yes | Create a key from a browser session on /me. Body fields: name, level (read, voter, or officer), expiresIn (7d, 30d, 90d, 180d, 365d, or never; default 30d). The secret is displayed once and cannot be retrieved again. The account email says a key was created and does not include the key. Body: name, level, expiresIn. |
DELETE |
/api/me/api-keys/:id |
voter | Yes | Revoke one of this account’s keys. Later calls with that secret are rejected. |
Vote PIN
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
POST |
/api/me/pin/keypad |
voter | Yes | Issue the scrambled phone keypad used to enter the vote PIN. |
POST |
/api/me/pin |
voter | Yes | Set the 4–8 digit vote PIN. Body: pin. |
POST |
/api/me/pin/verify |
voter | Yes | Verify the vote PIN and receive a short-lived pinToken for POST /api/elections/:id/vote. Body: pin. |
POST |
/api/me/pin/forgot |
voter | Yes | Start a PIN reset for the signed-in person. Completes with email MFA. |
POST |
/api/pin/forgot |
voter | No | Start a PIN reset from an email address. Sends a one-time code. Body: email. |
Identity
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/identity/methods |
read | No | Identity method types a person may bind: email, passkey, Web3, smart card, driver license, passport. |
GET |
/api/me/identity |
read | Yes | Full identity view for the signed-in person: emails, passkeys, Ethereum addresses, civic credentials. No trapdoor and no PIN. |
POST |
/api/identity/email/start |
voter | Yes | Start binding another email. One email is primary. Cap is 5. Body: email. |
POST |
/api/identity/web3/challenge |
voter | Yes | Challenge used to prove control of an Ethereum address before it is bound. Body: address. |
POST |
/api/identity/web3/verify |
voter | Yes | Bind a signature-verified Ethereum address. Only one address is active. Body: address, signature. |
POST |
/api/identity/smart-card/challenge |
voter | Yes | Challenge for binding a smart card. |
POST |
/api/identity/smart-card/verify |
voter | Yes | Bind a smart card after the reader signs the challenge. |
POST |
/api/identity/civic-id/verify |
voter | Yes | Bind a hashed driver license or passport. Images and full document numbers are not stored. |
GET |
/api/me/emails |
read | Yes | Email methods on this person. |
POST |
/api/me/emails/primary |
voter | Yes | Choose the primary email. Exactly one email is primary. Body: id or email. |
DELETE |
/api/me/emails/:id |
voter | Yes | Remove one email method. |
GET |
/api/me/passkeys |
read | Yes | Passkeys bound to this person. Cap is 5. |
DELETE |
/api/me/passkeys/:credentialId |
voter | Yes | Remove one passkey. |
GET |
/api/me/eth-accounts |
read | Yes | Verified Ethereum addresses and which one is active. |
POST |
/api/me/eth-accounts |
voter | Yes | Submit the signature that binds an Ethereum address. Body: address, signature. |
POST |
/api/me/eth-accounts/active |
voter | Yes | Switch the single active Ethereum address. Body: address. |
GET |
/api/me/credentials |
read | Yes | Smart cards and civic documents on this person. |
POST |
/api/persons/:id/person-key |
officer | Yes | Registrar or clerk binds the person key for someone on their jurisdiction. |
POST |
/api/persons/:id/methods |
officer | Yes | Officer adds an identity method to a person in their jurisdiction. |
POST |
/api/persons/:id/eth-accounts |
officer | Yes | Officer records an Ethereum address on a person. Body: address. |
POST |
/api/persons/:id/eth-accounts/active |
officer | Yes | Officer switches the person’s active Ethereum address. Body: address. |
GET |
/api/persons/:id/identity |
read | Yes | Registrar or clerk reads a person’s identity. A read-only key still needs that officer grant. |
GET |
/api/office/credentials |
read | Yes | Credentials waiting for civil-officer review. |
POST |
/api/persons/:id/methods/:methodId/review |
officer | Yes | Approve or reject a smart card or civic document. Body: decision. |
POST |
/api/persons/:id/methods/:methodId/revoke |
officer | Yes | Revoke an expired card or license. Revocation is an event. |
POST |
/api/integrations/credentials/status |
session | No | Credential-provider status callback. Uses the host provider secret header, not a personal API key. An API key is refused. |
Elections
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/elections |
read | No | Published elections. Counts follow the hourly disclosure rule. |
POST |
/api/elections |
officer | Yes | Clerk creates an election in a jurisdiction they already serve. Body: title, jurisdictionId, startTime, cutoffTime, questions or ballot. |
GET |
/api/elections/:id |
read | No | One election. When the caller is signed in, includes that person’s registration status. Choice is never included. |
PATCH |
/api/elections/:id |
officer | Yes | Clerk edits the ballot before the roll is frozen. |
PUT |
/api/elections/:id |
officer | Yes | Same edit as PATCH. |
GET |
/api/elections/:id/info |
read | No | Voter-facing questions, options, and supporting info. |
GET |
/api/elections/:id/info/:questionId/:optionId |
read | No | One option and its external links. |
GET |
/api/elections/:id/results |
read | No | Certified plurality or IRV results after tally. Empty of option counts before tally. |
GET |
/api/elections/:id/summary |
read | No | Short public status: state, window, disclosed ballot count, links. |
GET |
/api/elections/:id/ballots |
read | No | Disclosed ballot proofs for closed hours. Choice is not a field. |
GET |
/api/elections/:id/artifacts |
read | No | Auditor pack: roots, counts, and public checks. No Node private database. |
GET |
/api/elections/:id/l1 |
read | No | L1 certification status for the tally, when a tally exists. |
GET |
/api/elections/:id/tally-key |
read | No | Public tally ceremony view. The Node does not return a tally private key. |
GET |
/api/elections/:id/staff |
read | Yes | Election staff list. Caller must already be staff for that election. |
POST |
/api/elections/:id/staff |
officer | Yes | Platform admin approves election staff. Body: handle or userId. |
DELETE |
/api/elections/:id/staff |
officer | Yes | Platform admin revokes election staff. Body: handle or userId. |
GET |
/api/elections/:id/registrations |
read | Yes | Clerk, registrar, or disqualification officer lists the roll and requests. |
GET |
/api/elections/:id/registration-requests |
read | Yes | Clerk or registrar lists registration requests. Filter with ?status=. |
POST |
/api/elections/:id/register |
voter | Yes | Voter asks to join the roll. A registrar or clerk of that jurisdiction must approve. Body: identityCommitment. |
POST |
/api/elections/:id/registration-requests/:requestId/approve |
officer | Yes | Clerk or registrar approves a registration request and inserts the commitment. |
POST |
/api/elections/:id/registration-requests/:requestId/deny |
officer | Yes | Clerk or registrar declines a registration request. Body: reason. |
POST |
/api/elections/:id/freeze |
officer | Yes | Clerk freezes the eligible and disqualification roots. |
POST |
/api/elections/:id/vote |
voter | No | Submit one ballot. A signed-in voter must send pinToken from POST /api/me/pin/verify. The body is a proof plus ciphertext. Choice is not a public field. The same nullifier is accepted once. A read-only key is refused. Body: proof, public inputs, ciphertext, pinToken, identityCommitment when an external party is active. |
POST |
/api/elections/:id/disqualify |
officer | Yes | Disqualification officer applies a coded reason and an evidence hash. Body: identityCommitment, reasonCode, evidenceHash. |
POST |
/api/elections/:id/disqualify/revoke |
officer | Yes | Disqualification officer records a revocation event. |
POST |
/api/elections/:id/revoke |
officer | Yes | Same revocation event as /disqualify/revoke. |
GET |
/api/elections/:id/envelopes |
read | Yes | Tally operator reads encrypted envelopes after cutoff. Plaintext choice is not stored. |
POST |
/api/elections/:id/guardians |
officer | Yes | Tally operator enrolls a guardian in the opens-ballots ceremony. Non-production cryptography. |
POST |
/api/elections/:id/guardians/deals |
officer | Yes | Tally operator posts a guardian deal. |
GET |
/api/elections/:id/guardians/:index/inbox |
read | No | Encrypted shares addressed to one enrolled guardian index. |
POST |
/api/elections/:id/guardians/partials |
officer | Yes | Tally operator submits partial decryptions after cutoff. |
POST |
/api/elections/:id/tally |
officer | Yes | Tally operator posts the tally after cutoff. Invented counts that do not match opened ballots are rejected for opens-ballots. |
POST |
/api/elections/:id/certify-l1 |
officer | Yes | Tally operator asks the Node to mirror the tally to L1 when L1 env is set. |
External parties
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/elections/:id/parties |
read | No | External eligibility parties for an election. Endpoint URLs are included only for staff. |
POST |
/api/elections/:id/parties |
officer | Yes | Election staff registers an external eligibility party. Body: name, mode, operatorHandle. |
POST |
/api/elections/:id/parties/check |
officer | Yes | Staff checks whether a commitment is cleared to cast. Body: identityCommitment. |
PATCH |
/api/elections/:id/parties/:partyId |
officer | Yes | Staff changes a party status. Body: status. |
GET |
/api/elections/:id/parties/:partyId/rejections |
read | Yes | Staff lists party rejections. |
POST |
/api/elections/:id/parties/:partyId/reject |
officer | Yes | Staff or the party operator records a rejection. Body: identityCommitment, reasonCode, evidenceHash. |
POST |
/api/elections/:id/parties/:partyId/clear |
officer | Yes | Staff or the party operator clears a rejection. Body: identityCommitment, evidenceHash. |
POST |
/api/elections/:id/parties/:partyId/attest |
officer | Yes | Staff or the party operator attests a commitment. Body: identityCommitment, expiresAt, evidenceHash. |
Jurisdictions
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/jurisdictions |
read | No | Jurisdictions on this Node. Officer lists are included only for officers. |
POST |
/api/jurisdictions |
officer | Yes | Platform admin creates a jurisdiction. Body: name, metadataURI. The Node assigns a UUID id; a caller cannot choose it.. |
GET |
/api/jurisdictions/:id |
read | No | One jurisdiction. |
GET |
/api/jurisdictions/:id/roles |
read | Yes | Officers granted on a jurisdiction. Caller must already be an officer. |
POST |
/api/jurisdictions/:id/roles |
officer | Yes | Platform admin grants clerk, registrar, disqualification officer, tally operator, or election staff. Body: role, handle or userId. |
DELETE |
/api/jurisdictions/:id/roles |
officer | Yes | Platform admin revokes a jurisdiction grant. Body: role, handle or userId. |
POST |
/api/admin/roles |
officer | Yes | Same grant as POST /api/jurisdictions/:id/roles. Body: jurisdictionId, role, handle or userId. |
POST |
/api/admin/grant |
officer | Yes | Alias of POST /api/admin/roles. Body: jurisdictionId, role, handle or userId. |
GET |
/api/users |
read | Yes | Platform admin lists accounts and their jurisdiction grants. A read-only key may list. It cannot change roles. |
PATCH |
/api/users/:id |
officer | Yes | Platform admin sets a role the account is already allowed to grant: voter, observer, clerk, registrar, disqualification_officer, tally_operator, or election_staff. Body: role. |
GET |
/api/reason-codes |
read | No | Public disqualification reason catalog. |
Pages
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/pages |
read | No | Published public pages and the shared-contract site view. |
GET |
/api/pages/:slug |
read | No | One published page. |
GET |
/api/site |
read | No | Public site record, including pinned contract addresses. |
GET |
/api/office/site |
read | Yes | Clerk reads the office site record. |
PATCH |
/api/office/site |
officer | Yes | Clerk pins shared contract addresses. Environment pins win over the stored site. |
GET |
/api/office/pages |
read | Yes | Clerk lists CMS pages, including drafts they may edit. |
POST |
/api/office/pages |
officer | Yes | Clerk creates a page. |
GET |
/api/office/pages/:id |
read | Yes | Clerk reads one CMS page. |
PATCH |
/api/office/pages/:id |
officer | Yes | Clerk edits a CMS page. |
DELETE |
/api/office/pages/:id |
officer | Yes | Clerk deletes a CMS page. |
Terms
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/terms |
read | No | Current Terms of Use metadata and whether the caller has accepted this PDF hash. |
GET |
/api/terms.pdf |
read | No | Terms PDF bytes. SHA-256 is in the X-Pdf-SHA256 header. |
GET |
/terms.pdf |
read | No | Same Terms PDF as GET /api/terms.pdf. |
POST |
/api/terms/view |
voter | No | Record that the signed-in person viewed the Terms. |
POST |
/api/terms/accept |
voter | Yes | Accept the current Terms. Acceptance stores the SHA-256 of the PDF bytes. Body: acceptedTerms. |
Feedback
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/feedback |
read | No | Feedback form limits, categories, and whether the operator inbox is configured. |
POST |
/api/feedback |
voter | No | Send one feedback message. This is also how a person contacts support. Rate-limited. A read-only key is refused because the call sends mail. Body: category, name, email, message, acceptedTerms. |
Receipts
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/receipts/metrics |
read | No | Public receipt metrics and hourly turnout. No candidate and no option. |
POST |
/api/receipts/verify |
read | No | Check a hash-only receipt or its locked PDF. Returns whether the ballot counted. Never returns a choice. Body: proof or receipt text, or PDF bytes. |
POST |
/api/receipts/email |
voter | Yes | Email the voter their hash-only receipt after the ballot is accepted. |
POST |
/api/receipts/pdf |
voter | Yes | Download the locked receipt PDF for a ballot this caller may access. |
Outcomes
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/outcomes |
read | No | Every election grouped before, during, and after voting. No unofficial option counts during the open window. |
GET |
/api/outcomes/:id |
read | No | One election’s public outcome monitor. |
GET |
/api/outcomes/reports |
read | No | Issued official outcome reports. |
GET |
/api/outcomes/reports/:id |
read | No | One official outcome report record. |
GET |
/api/outcomes/reports/:id/pdf |
read | No | Locked official outcome PDF. |
POST |
/api/outcomes/verify |
read | No | Check an official outcome PDF was not modified. Body: pdf bytes or id. |
GET |
/api/me/outcome-subscriptions |
read | Yes | Elections whose official PDF this person will be emailed. Voting subscribes them by default. |
PUT |
/api/me/outcome-subscriptions/:electionId |
voter | Yes | Subscribe or confirm a subscription to an official outcome PDF. |
POST |
/api/me/outcome-subscriptions |
voter | Yes | Subscribe the caller to an election’s official outcome PDF. Body: electionId. |
GET |
/api/admin/outcome-report-template |
read | Yes | Platform admin reads the official outcome PDF template. QR and hash seals stay required. |
PATCH |
/api/admin/outcome-report-template |
officer | Yes | Platform admin edits template copy. QR and hash seals cannot be removed. |
POST |
/api/admin/outcome-report-template/preview |
officer | Yes | Platform admin previews the outcome PDF template. |
Explorer
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/explorer/disclosure |
read | No | Hourly disclosure window the explorer uses. |
GET |
/api/explorer/blocks |
read | No | Civic L2 blocks. |
GET |
/api/explorer/blocks/:n |
read | No | One civic L2 block. |
GET |
/api/explorer/txs/:hash |
read | No | One civic L2 transaction. Ballot plaintext is not a field. |
GET |
/api/explorer/nullifiers/:value |
read | No | Whether a nullifier was accepted. The nullifier does not reveal the choice or the person. |
GET |
/api/explorer/search |
read | No | Search blocks, transactions, and elections. |
GET |
/api/explorer/elections/:id |
read | No | Explorer view of one election. |
POST |
/api/explorer/ingest |
officer | No | Operator ingest of civic L2 events. Send the host ingest secret in X-Republic-Ingest-Secret. A personal API key does not replace that secret. Minimum key level when a key is also sent: officer. |
Polls
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/polls |
read | No | Token polls when POLLS_ENABLED is on. Polls are signal, not binding elections. Omitted from the Node when the flag is off. |
GET |
/api/polls/:id |
read | No | One token poll. |
GET |
/api/polls/:id/weight |
read | No | Read-only token weight for an address. The Node does not move tokens. |
GET |
/api/polls/:id/typed-data |
read | No | EIP-712 typed data a holder signs. Query: address, choices. |
POST |
/api/polls/:id/ballots |
voter | No | Submit a signed token-poll ballot. No Republic account is required. A read-only key is refused. |
POST |
/api/polls/:id/tally |
voter | Yes | Any signed-in person may ask the Node to tally a closed token poll. Counts come from accepted ballots. |
GET |
/api/polls/:id/results |
read | No | Token poll results after tally. |
GET |
/api/polls/:id/artifacts |
read | No | Token poll auditor pack. |
GET |
/api/polls/:id/ballots.json |
read | No | Disclosed token-poll ballots. |
GET |
/api/polls/:id/outcome.pdf |
read | No | Token poll outcome PDF. |
| Method | Path | Minimum key | Sign-in | What a bot does |
|---|---|---|---|---|
GET |
/api/mail/templates |
read | Yes | Platform admin lists operator mail templates stored on the Node. Mail is never written to civic L2. |
GET |
/api/mail/templates/:id |
read | Yes | Platform admin previews one operator mail template, including api_key.created. |
GET |
/api/mail/outbox |
read | Yes | Platform admin lists queued operator mail. Bodies stay on the detail route. |
GET |
/api/mail/outbox/:id |
read | Yes | Platform admin reads one outbox message, including text and HTML. |