Session — API reference
The dashboard session: the credential a browser holds, and the only one it ever holds. An API key is a machine credential and is never used from a page.
Signing in is one action for the person: the page fetches a challenge
(POST /v1/accounts/challenge), the wallet signs it — free, no transaction, nothing
leaves the wallet — and the signature comes to POST /v1/session, which sets an
httpOnly cookie. The session survives reloads and navigation, slides forward as it is
used, and is restored silently with GET /v1/session.
Because the credential is a cookie, every unsafe method additionally needs the
X-CSRF-Token header, whose value is the csrf_token of the session response. A
cross-site page cannot read that response, so it cannot produce the header.
| Method | Path | Summary |
|---|---|---|
GET | /v1/session | Restore the session silently |
POST | /v1/session | Sign in to the dashboard |
DELETE | /v1/session | Sign out |
POST | /v1/session/refresh | Extend the session |
POST | /v1/session/revoke-all | Sign out everywhere |
GET | /v1/session/history | Recent sign-ins |
Generated from openapi.yaml at build time. Base URL https://api.tenergy.me/v1, or https://api-nile.tenergy.me/v1 on Nile (Environments). Every request below is signed as in Authentication unless its Auth line says otherwise.
Restore the session silently
GET /v1/session · getSession
Auth: Dashboard session cookie + X-CSRF-Token.
What the dashboard calls on every load. Answers with the live session, or
1013 session_expired when the browser has none — which is not an error condition to
report to the person, only the signal to show the sign-in screen.
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | 1013 session_expired — no session, or it expired or was signed out. |
500 | Something broke on our side. |
Response fields (Session)
| Field | Type | Required | Description |
|---|---|---|---|
account_id | string | yes | For the “Account ID (for support)” field. Nothing in a UI has to show it anywhere else — the account’s title is display_name, or the shortened owner_address. |
account_status | enum: unfunded, active, suspended, closed | yes | |
display_name | string | null | ||
owner_address | string | null | The wallet that owns this account; signing in with it is how it is recovered. | |
address | string | yes | The address that signed in. The owner’s, unless a member was invited. |
role | enum: owner, editor, viewer | null | yes | This signer’s role on the account. It, and nothing else, decides what they may do. |
network | enum: mainnet, nile | ||
csrf_token | string | yes | Echo in X-CSRF-Token on every POST, PATCH and DELETE of this session. |
expires_at | string (date-time) | yes | |
created_at | string (date-time) | ||
ttl_seconds | integer | The full session lifetime, in seconds, as renewal resets it. |
Sign in to the dashboard
POST /v1/session · createSession
Auth: Public — no credentials.
Verifies a challenge signed by a TRON address and opens a browser session, returned as
an httpOnly cookie. If the address owns no account on this brand yet, one is created
here — status: unfunded, the same account POST /v1/accounts would have made — so a
first visit and a return visit are the same single action.
Signing the challenge is free and is not a transaction: no funds move and no key leaves the wallet.
The response body carries csrf_token. Send it as X-CSRF-Token on every subsequent
POST, PATCH or DELETE made with this session.
Request body
JSON (SessionRequest), required.
| Field | Type | Required | Description |
|---|---|---|---|
address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
nonce | string | yes | From POST /v1/accounts/challenge. Single use. |
signature | string | yes | The wallet’s signature over the challenge message. |
Responses
| Status | Meaning |
|---|---|
201 | Signed in. The session cookie is set. |
400 | Malformed request — bad JSON, unknown field, wrong type. |
401 | 1010 challenge_invalid — unknown, expired or reused nonce, or a signature that does not recover the address. |
429 | Too many requests. |
500 | Something broke on our side. |
Response fields (Session)
| Field | Type | Required | Description |
|---|---|---|---|
account_id | string | yes | For the “Account ID (for support)” field. Nothing in a UI has to show it anywhere else — the account’s title is display_name, or the shortened owner_address. |
account_status | enum: unfunded, active, suspended, closed | yes | |
display_name | string | null | ||
owner_address | string | null | The wallet that owns this account; signing in with it is how it is recovered. | |
address | string | yes | The address that signed in. The owner’s, unless a member was invited. |
role | enum: owner, editor, viewer | null | yes | This signer’s role on the account. It, and nothing else, decides what they may do. |
network | enum: mainnet, nile | ||
csrf_token | string | yes | Echo in X-CSRF-Token on every POST, PATCH and DELETE of this session. |
expires_at | string (date-time) | yes | |
created_at | string (date-time) | ||
ttl_seconds | integer | The full session lifetime, in seconds, as renewal resets it. |
Sign out
DELETE /v1/session · deleteSession
Auth: Dashboard session cookie + X-CSRF-Token.
Revokes this session server-side and clears the cookie. Other sessions of the same account — another browser, another device — are untouched.
Responses
| Status | Meaning |
|---|---|
204 | Signed out. No body. |
401 | Missing, malformed or rejected credentials. |
403 | 1014 csrf_token_invalid — the X-CSRF-Token header is missing or wrong. |
500 | Something broke on our side. |
Extend the session
POST /v1/session/refresh · refreshSession
Auth: Dashboard session cookie + X-CSRF-Token.
Slides the expiry forward and reissues the cookie with a fresh lifetime. The session is also renewed automatically as it is used, so this is for a page that has been open a long time without making a request.
Responses
| Status | Meaning |
|---|---|
200 | Extended |
401 | Missing, malformed or rejected credentials. |
403 | 1014 csrf_token_invalid. |
500 | Something broke on our side. |
Response fields (Session)
| Field | Type | Required | Description |
|---|---|---|---|
account_id | string | yes | For the “Account ID (for support)” field. Nothing in a UI has to show it anywhere else — the account’s title is display_name, or the shortened owner_address. |
account_status | enum: unfunded, active, suspended, closed | yes | |
display_name | string | null | ||
owner_address | string | null | The wallet that owns this account; signing in with it is how it is recovered. | |
address | string | yes | The address that signed in. The owner’s, unless a member was invited. |
role | enum: owner, editor, viewer | null | yes | This signer’s role on the account. It, and nothing else, decides what they may do. |
network | enum: mainnet, nile | ||
csrf_token | string | yes | Echo in X-CSRF-Token on every POST, PATCH and DELETE of this session. |
expires_at | string (date-time) | yes | |
created_at | string (date-time) | ||
ttl_seconds | integer | The full session lifetime, in seconds, as renewal resets it. |
Sign out everywhere
POST /v1/session/revoke-all · revokeAllSessions
Auth: Dashboard session cookie + X-CSRF-Token.
Revokes every session of the signed-in wallet on this account — every browser and
device, this one included — and clears the cookie. Sessions of other members are not
touched. Writes an audit row (session.revoke_all). Dashboard session only, member
role viewer or above; every API key is refused.
Responses
| Status | Meaning |
|---|---|
204 | Signed out everywhere. No body. |
401 | Missing, malformed or rejected credentials. |
403 | 1014 csrf_token_invalid. |
500 | Something broke on our side. |
Recent sign-ins
GET /v1/session/history · getSessionHistory
Auth: Dashboard session cookie + X-CSRF-Token.
The last ten dashboard sign-ins of the signed-in wallet on this account, newest
first: when, from which IP, with which wallet. A sign-in is recorded when
POST /v1/session issues a session; the history starts on 2026-09-25.
Sign-ins of other members are not listed: showing one member’s IP addresses to another
is an access decision that has not been taken. Dashboard session only, member role
viewer or above.
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | Missing, malformed or rejected credentials. |
500 | Something broke on our side. |
Response fields
| Field | Type | Required | Description |
|---|---|---|---|
data | array of object (SignIn) | yes | |
data[].signed_in_at | string (date-time) | yes | |
data[].ip | string | null | yes | |
data[].address | string | yes | Base58Check TRON address (starts with T, 34 characters). |
Example 200 response, from the contract (illustrative values — live numbers come from the API):
{
"data": [
{
"signed_in_at": "2026-09-25T09:41:12.000Z",
"ip": "203.0.113.10",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
}
]
}