Skip to content

Accounts

SESAM provides two related authentication flows:

  • REST API authentication uses a long-lived access token for API requests.
  • One-time browser login uses a short-lived, single-use ticket to establish a normal browser session.

REST API authentication

A typical API client first retrieves an access token and then sends that token in the Authorization header of its subsequent REST requests.

POST /api/v1/accounts/login/

Use the login endpoint to acquire an access token. Send that token with every authenticated REST request. Setting the request and response content type to application/json usually simplifies client implementations.

sequenceDiagram
    participant C as Client
    participant S as SESAM API
    C->>+S: POST /api/v1/accounts/login/ (username, password)
    S->>-C: authentication token ab54cd....
Example Code
import requests

with requests.Session() as session:
    data = {"username": "<username>", "password": "<password>"}
    response = session.post("https://sesam.co4e.com/api/v1/accounts/login", data=data)
    token = response.json().get("key")
    session.headers.update(
        {
            "Content-type": "application/json",
            "Accept": "application/json",
            "Authorization": f"Token {token}",
        }
    )

POST /api/v1/accounts/logout/

Use the logout endpoint to invalidate the access token returned by the login endpoint.

sequenceDiagram
    participant C as Client
    participant S as SESAM API
    C->>+S: POST /api/v1/accounts/logout/
    S->>-C: OK
Example Code
1
2
3
4
5
import requests

with requests.Session() as session:
    # ... do some work ...
    response = session.post("https://sesam.co4e.com/api/v1/accounts/logout")

Account plan, limits, and usage

GET /api/v1/accounts/me/

Returns the effective SESAM plan of the authenticated user together with its public capabilities, limits, and current daily quota usage. The endpoint accepts no user ID and always returns information for the user identified by the REST access token.

HTTP
1
2
3
GET /api/v1/accounts/me/
Authorization: Token <rest-api-token>
Accept: application/json

A successful response is 200 OK:

JSON
{
  "plan": {
    "name": "Basic",
    "features": {
      "projects": true,
      "rest_api": true,
      "scenario_editor": true,
      "scenario_custom_uploads": true,
      "scenario_public_sharing": false,
      "simulation_microscopic": true,
      "simulation_mesoscopic": false,
      "simulation_builtin_scenarios": true,
      "simulation_download_outputs": true,
      "simulation_public_sharing": false
    },
    "limits": {
      "scenario": {
        "max_area_square_meters": 4000000,
        "max_duration_seconds": 900,
        "default_duration_seconds": 600,
        "builds_per_day": 15,
        "custom_upload_max_bytes": 31457280,
        "custom_uploads_per_day": 15
      },
      "simulation": {
        "runs_per_day": 50
      },
      "storage": {
        "retention_seconds": 432000
      }
    }
  },
  "usage": {
    "scenario_builds": {"used": 3, "limit": 15, "remaining": 12},
    "simulation_runs": {"used": 17, "limit": 50, "remaining": 33},
    "scenario_uploads": {"used": 2, "limit": 15, "remaining": 13}
  }
}

Scenario area values are in square meters. Scenario durations and storage retention are in seconds. Upload sizes are in bytes. Daily quota fields cover the current accounting day and have the following meanings:

  • used: usage recorded by the same accounting mechanism that enforces Builder, simulation, and upload quotas;
  • limit: maximum permitted usage per day;
  • remaining: unused quota, clamped to zero when usage reaches or exceeds the limit.

A null limit means that the value is unlimited. For an unlimited quota, both limit and remaining are null, while used still reports current usage. SESAM does not expose its internal unlimited sentinel.

plan.limits.storage.retention_seconds is the plan's guaranteed retention period. A null value means unlimited retention. Internal cleanup grace periods are operational details and are not included in this value.

The feature booleans indicate whether the corresponding capability is available to the account. A request without valid REST authentication receives 401 Unauthorized.

One-time browser login

One-time browser login lets an authenticated integration such as Baustellenatlas open SESAM in a new browser window without asking the user to log in manually. It consists of two endpoints:

  1. The integration creates a browser login ticket through the authenticated REST API.
  2. The browser opens the returned URL and redeems the ticket as a top-level navigation.

The ticket is valid for 120 seconds and can be redeemed exactly once. Successful redemption establishes a normal SESAM browser session; the ticket is not a replacement for the REST API access token.

POST /api/v1/accounts/browser-login-tickets/

Creates a browser login ticket and returns the URL used to redeem it.

The request requires normal SESAM REST token authentication and a plan with the has_rest_api_access feature:

HTTP
1
2
3
4
5
6
7
POST /api/v1/accounts/browser-login-tickets/
Authorization: Token <rest-api-token>
Content-Type: application/json

{
  "target_path": "/analyzer/12/34"
}

target_path must start with exactly one /, be a local path without a scheme, host, fragment, or backslash redirect variant, and resolve to an existing Django route. Query parameters are preserved. The browser login route itself cannot be used as a target. The target determines only the first page displayed after login: it does not grant access to the referenced object and is not an authorization scope. Existing ownership checks continue to apply.

A successful response is 201 Created:

JSON
1
2
3
4
{
  "expires_at": "2026-08-11T12:02:00Z",
  "login_url": "https://sesam.example/accounts/browser-login/?ticket=PLACEHOLDER_ONE_TIME_BROWSER_LOGIN_TICKET"
}

The origin of login_url is environment-specific. The clear-text ticket is returned only in this creation response; SESAM stores only its SHA-256 hash.

Treat login_url as a temporary sensitive credential. Do not log it, store it permanently, include it in monitoring or analytics, or attempt to reuse it. Opening it in a browser profile that already has a SESAM session changes the shared SESAM session used by other tabs in that profile.

The response includes Cache-Control: no-store and Pragma: no-cache. Relevant creation responses are:

Status Meaning
201 Created Ticket created successfully
400 Bad Request Invalid or missing target_path
401 Unauthorized Missing or invalid REST authentication
403 Forbidden User does not have has_rest_api_access

Browser JavaScript must call this endpoint from an origin approved by the SESAM CORS policy.

GET /accounts/browser-login/?ticket=<ticket>

Open the returned login_url as a top-level browser navigation. The redemption endpoint does not require CORS. It accepts only the ticket value; the redirect destination was already validated and stored when the authenticated client created the ticket.

Successful redemption consumes the ticket, establishes a normal SESAM browser session, and redirects to the stored target_path without including the ticket in the destination URL. The resulting session follows the normal session settings and is not restricted to target_path.

Missing, malformed, expired, consumed, inactive-user, and no-longer-entitled tickets all receive the same generic 400 Bad Request response without establishing a session.

Redemption responses include Cache-Control: no-store, Pragma: no-cache, and Referrer-Policy: no-referrer.

Production operators must keep the ticket query parameter out of every reverse-proxy, load-balancer, monitoring, and APM log.