> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.ouster.com/sensor-docs/firmware/3.2/api-reference/ouster-http-api/authentication/post-auth-login/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ouster.com/_mcp/server. # Validate JWT and issue session token POST http://os-992244000006.local/api/v1/auth/login Content-Type: application/json Validates JWT from auth server and issues session token. **JWT Validation (security-critical order):** 1. Signature verification (ECDSA P-256) 2. Audience check (must match device serial number) 3. POH expiration check (`exp_poh` vs current POH) 4. Nonce validation (single-use, must be pending) **Token Usage Types:** - `cookie`: Sets HTTP-only cookie, returns success message - `bearer`: Returns session token in body, no cookie set **Security Properties:** - All validation failures return HTTP 401 with no information leakage - Nonce marked as used after successful validation - Session tokens expire based on POH, not wall-clock time - Cookie security: `http_only=True`, `same_site='Strict'`, `secure=True` (HTTPS) Reference: https://docs.ouster.com/sensor-docs/firmware/api-reference/ouster-http-api/authentication/post-auth-login ## Request ### Body (application/json) This endpoint expects a LoginRequest. - `token` (string, required) — JWT signed by auth server (ECDSA P-256) - `token_usage` (enum, required) — Token usage type: - `cookie`: Session token delivered via HTTP-only cookie (browser clients) - `bearer`: Session token delivered via Authorization Bearer header (API clients) - Allowed values: `cookie`, `bearer` ## Response ### 200 Login successful (bearer token mode) - `token` (string, required) — Session token for bearer authentication (base64url, 22 chars) ## Errors ### 400 Bad Request Error Invalid request (missing/malformed fields) - `title` (string, optional) — Error title - `description` (string, optional) — Error description ### 401 Unauthorized Error JWT validation failed (no distinguishing details): - Invalid signature - Wrong audience (device serial number) - Expired POH - Invalid/expired/reused nonce - Malformed JWT - `title` (string, optional) — Error title - `description` (string, optional) — Error description ## Examples **Request** ```json { "token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...", "token_usage": "cookie" } ``` **Response** ```json { "token": "x1y2z3a4b5c6d7e8f9g0h1" } ``` **SDK Code** ```python Authentication_postAuthLogin_example import requests url = "http://os-992244000006.local/api/v1/auth/login" payload = { "token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...", "token_usage": "cookie" } headers = {"Content-Type": "application/json"} response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```javascript Authentication_postAuthLogin_example const url = 'http://os-992244000006.local/api/v1/auth/login'; const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"token":"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...","token_usage":"cookie"}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Authentication_postAuthLogin_example package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "http://os-992244000006.local/api/v1/auth/login" payload := strings.NewReader("{\n \"token\": \"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...\",\n \"token_usage\": \"cookie\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Content-Type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Authentication_postAuthLogin_example require 'uri' require 'net/http' url = URI("http://os-992244000006.local/api/v1/auth/login") http = Net::HTTP.new(url.host, url.port) request = Net::HTTP::Post.new(url) request["Content-Type"] = 'application/json' request.body = "{\n \"token\": \"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...\",\n \"token_usage\": \"cookie\"\n}" response = http.request(request) puts response.read_body ``` ```java Authentication_postAuthLogin_example import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("http://os-992244000006.local/api/v1/auth/login") .header("Content-Type", "application/json") .body("{\n \"token\": \"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...\",\n \"token_usage\": \"cookie\"\n}") .asString(); ``` ```php Authentication_postAuthLogin_example request('POST', 'http://os-992244000006.local/api/v1/auth/login', [ 'body' => '{ "token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...", "token_usage": "cookie" }', 'headers' => [ 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` ```csharp Authentication_postAuthLogin_example using RestSharp; var client = new RestClient("http://os-992244000006.local/api/v1/auth/login"); var request = new RestRequest(Method.POST); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"token\": \"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...\",\n \"token_usage\": \"cookie\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift Authentication_postAuthLogin_example import Foundation let headers = ["Content-Type": "application/json"] let parameters = [ "token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...", "token_usage": "cookie" ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "http://os-992244000006.local/api/v1/auth/login")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers request.httpBody = postData as Data let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ```