Skip to content

Protocol Reference

Summary

The 2Wee protocol is the JSON contract between client and server. This page is the authoritative reference for the wire format. For detailed explanations of each structure, see the linked pages.

Transport

All communication is synchronous HTTPS request/response. The client makes GET or POST requests. The server returns JSON.

ActionMethodContent-Type
Fetch any screenGETapplication/json (ScreenContract)
Save changesPOSTapplication/json (SaveChangeset) → ScreenContract
Delete recordPOSTapplication/json (DeleteRequest) → ScreenContract
Execute actionPOSTapplication/json (ActionRequest) → ActionResponse
AuthenticatePOSTapplication/json (AuthRequest) → AuthResponse
Validate fieldGETapplication/json (ValidateResponse)

Only GET and POST are used. No PUT, PATCH, or DELETE. This is a screen rendering protocol, not a REST API.

No WebSocket, no persistent connections, no heartbeats.

Authentication

JWT Bearer tokens in the Authorization header:

Authorization: Bearer <jwt_token>

If the server returns 401 Unauthorized, the client redirects to the login screen. See Authentication for the full login flow.

URL architecture

The client takes a base URL (e.g., http://2wee.test/terminal) and uses it for two entry points:

  • {base_url}/menu/main
  • {base_url}/auth/login

All other paths come from the server as absolute paths (from the host root). The client resolves them by prepending only the scheme and host. See Routes for URL patterns and examples.

Response types

ScreenContract

Every server response to a screen request is a ScreenContract. See Screen Types for the full field reference.

json
{
  "layout": "Card",
  "title": "Customer Card - 10000",
  "screen_id": "customer_card",
  "sections": [],
  "lines": null,
  "menu": null,
  "status": null,
  "work_date": "10-03-2026",
  "locale": {},
  "ui_strings": null,
  "auth_action": null,
  "user_display_name": "Erik Y.",
  "actions": {
    "save": "/screen/customer_card/10000/save",
    "delete": "/screen/customer_card/10000/delete",
    "create": "/screen/customer_card/new"
  },
  "lines_overlay_pct": 50,
  "screen_actions": []
}

Layout types: Card, List, HeaderLines, Grid, Menu.

ValidateResponse

Returned by the blur validation endpoint. See Lookups for details.

json
{
  "valid": true,
  "autofill": {
    "city": "Tórshavn"
  },
  "error": null
}
PropertyTypePurpose
validboolWhether the value exists in the related table
autofillmapField values to write to the card (only when valid)
errorstringError message (only when invalid)

AuthResponse

Returned by the login endpoint. See Authentication for details.

json
{
  "success": true,
  "token": "eyJ...",
  "error": null,
  "screen": {}
}
PropertyTypePurpose
successboolWhether authentication succeeded
tokenstringJWT token (only on success)
errorstringError message (only on failure)
screenScreenContractInitial screen (only on success)

Client → Server payloads

SaveChangeset (Ctrl+S)

Posted to the actions.save URL. See Saving for details.

json
{
  "screen_id": "customer_card",
  "record_id": "10000",
  "changes": {
    "name": "Acme Corporation",
    "post_code": "100"
  },
  "action": null,
  "lines": []
}
PropertyTypePurpose
screen_idstringEchoed from ScreenContract.screen_id
record_idstringRecord identifier
changesmapChanged field values (field_id → value)
actionstringOptional action hint (e.g., null for saves)
linesstring[][]Grid line data for HeaderLines and Grid screens

For HeaderLines and Grid screens, lines contains the full grid data. Each inner array is one row, with values ordered by column definition. See HeaderLines and Grids for details.

DeleteRequest (Ctrl+D)

Posted to the actions.delete URL. See Deleting for details.

json
{
  "screen_id": "customer_card",
  "record_id": "10000"
}

The path parameter is authoritative — the server identifies the record from the URL path.

ActionRequest (Ctrl+A)

Posted to the action's endpoint URL. See Screen Actions for details.

json
{
  "action_id": "send_email",
  "screen_title": "Sales Order - SO-1001",
  "record_id": "SO-1001",
  "fields": {
    "to": "ap@cannongroup.example",
    "subject": "Sales Order SO-1001"
  }
}
PropertyTypePurpose
action_idstringAction identifier (from ActionDef)
screen_titlestringHuman-readable screen title
record_idstringFrom ScreenContract.record_id, or null if empty
fieldsobjectForm field values (empty for Simple and Confirm kinds)

The server returns an ActionResponse:

json
{
  "success": true,
  "message": "Email sent to ap@cannongroup.example.",
  "screen": null,
  "error": null
}
PropertyTypePurpose
successboolWhether the action succeeded
messagestringSuccess message (shown in result modal)
screenScreenContractUpdated screen (replaces current if provided)
errorstringError message (shown in result modal)
redirect_urlstringNavigate to this screen after dismissing the result modal
push_urlstringPush a new screen onto navigation history (without a modal)

AuthRequest

Posted to the auth_action URL. See Authentication for details.

json
{
  "fields": {
    "username": "admin",
    "password": "admin"
  }
}

Backwards compatibility

The 2Wee protocol follows an additive-only evolution model — the same model the web uses.

What this means in practice:

  • New field types, new optional properties, new layout kinds may be added at any time
  • Servers that don't send new optional fields get the documented default — nothing breaks
  • Clients that don't yet understand a new property ignore it — nothing breaks
  • Old clients work against new servers; old servers work against new clients

What will never happen after 1.0:

  • Removing a field or property
  • Renaming a field or property
  • Changing the meaning of an existing field
  • Making an optional field required

This is the actual compatibility contract. There is no on-wire version number — the design makes mismatches structurally unlikely rather than just detectable. If a true breaking change is ever required, it will be introduced via a new URL namespace (e.g., /v2/) so old and new implementations can coexist.

Detailed references

TopicPage
ScreenContract fields, layout typesScreen Types
Sections and fieldsCards, Field types
Tables (TableSpec), columns, rowsLists
Menus (MenuSpec)Menus
Route patterns, query parametersRoutes
Full-screen editable gridsGrids
Lookup endpoints, autofill, validationLookups
Screen actions, ActionRequest/ResponseScreen Actions
Localization, UI stringsLocalization