# Authentication

## Authenticate with Privy token

> Verify a Privy token and return the user's info including roles and a Meshmap session token. Creates a new user if one does not exist.

```json
{"openapi":"3.0.0","info":{"title":"Meshmap API v1","version":"1.0.0"},"servers":[{"url":"/api/v1","description":"API v1 base URL"}],"paths":{"/auth/privy":{"post":{"summary":"Authenticate with Privy token","description":"Verify a Privy token and return the user's info including roles and a Meshmap session token. Creates a new user if one does not exist.","tags":["Authentication"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrivyAuthRequest"}}}},"responses":{"200":{"description":"Authentication successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrivyAuthResponse"}}}},"400":{"description":"Token is required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"PrivyAuthRequest":{"type":"object","required":["token"],"properties":{"token":{"type":"string","description":"Privy authentication token"}}},"PrivyAuthResponse":{"type":"object","required":["user","meshmapSessionToken"],"properties":{"user":{"type":"object","required":["id","email","firstName","lastName","roles","isAdmin","hasOpsAccess"],"properties":{"id":{"type":"string","description":"User ID"},"email":{"type":"string","nullable":true,"description":"User email"},"firstName":{"type":"string","nullable":true,"description":"User first name"},"lastName":{"type":"string","nullable":true,"description":"User last name"},"roles":{"type":"array","items":{"type":"string"},"description":"User roles"},"isAdmin":{"type":"boolean","description":"Whether the user has admin role"},"hasOpsAccess":{"type":"boolean","description":"Whether the user has ops or admin access"}}},"meshmapSessionToken":{"type":"string","description":"JWT session token for authenticating with Meshmap APIs"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"oneOf":[{"type":"string","description":"Error message"},{"type":"array","items":{"type":"object","required":["code","message","path"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"path":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"description":"Error path"}}}}]}}}}}}
```

## Get current user profile

> Get the profile information for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Meshmap API v1","version":"1.0.0"},"servers":[{"url":"/api/v1","description":"API v1 base URL"}],"security":[{"SessionToken":[]}],"components":{"securitySchemes":{"SessionToken":{"type":"apiKey","in":"header","name":"Authorization","description":"Session token in Bearer format: Bearer <token>"}},"schemas":{"UserSchema":{"type":"object","required":["id","createdAt"],"properties":{"id":{"type":"string","description":"Unique user identifier"},"email":{"type":"string","nullable":true,"description":"User email address"},"firstName":{"type":"string","nullable":true,"description":"User first name"},"lastName":{"type":"string","nullable":true,"description":"User last name"},"phoneNumber":{"type":"string","nullable":true,"description":"User phone number"},"username":{"type":"string","nullable":true,"description":"User username"},"createdAt":{"type":"string","format":"date-time","description":"User creation timestamp"},"imageUrl":{"type":"string","nullable":true,"description":"User profile image URL"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"oneOf":[{"type":"string","description":"Error message"},{"type":"array","items":{"type":"object","required":["code","message","path"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"path":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"description":"Error path"}}}}]}}}}},"paths":{"/user":{"get":{"summary":"Get current user profile","description":"Get the profile information for the authenticated user","tags":["Authentication"],"responses":{"200":{"description":"User profile retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}},"401":{"description":"Unauthorized - invalid or missing session token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Update current user profile

> Update the username for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Meshmap API v1","version":"1.0.0"},"servers":[{"url":"/api/v1","description":"API v1 base URL"}],"security":[{"SessionToken":[]}],"components":{"securitySchemes":{"SessionToken":{"type":"apiKey","in":"header","name":"Authorization","description":"Session token in Bearer format: Bearer <token>"}},"schemas":{"UserPatchRequest":{"type":"object","required":["username"],"properties":{"username":{"type":"string","minLength":1,"description":"New username for the user"}}},"UserSchema":{"type":"object","required":["id","createdAt"],"properties":{"id":{"type":"string","description":"Unique user identifier"},"email":{"type":"string","nullable":true,"description":"User email address"},"firstName":{"type":"string","nullable":true,"description":"User first name"},"lastName":{"type":"string","nullable":true,"description":"User last name"},"phoneNumber":{"type":"string","nullable":true,"description":"User phone number"},"username":{"type":"string","nullable":true,"description":"User username"},"createdAt":{"type":"string","format":"date-time","description":"User creation timestamp"},"imageUrl":{"type":"string","nullable":true,"description":"User profile image URL"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"oneOf":[{"type":"string","description":"Error message"},{"type":"array","items":{"type":"object","required":["code","message","path"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"path":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"description":"Error path"}}}}]}}}}},"paths":{"/user":{"patch":{"summary":"Update current user profile","description":"Update the username for the authenticated user","tags":["Authentication"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPatchRequest"}}}},"responses":{"200":{"description":"User profile updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - invalid or missing session token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Username is already taken","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Remove user profile image

> Delete the profile image for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Meshmap API v1","version":"1.0.0"},"servers":[{"url":"/api/v1","description":"API v1 base URL"}],"security":[{"SessionToken":[]}],"components":{"securitySchemes":{"SessionToken":{"type":"apiKey","in":"header","name":"Authorization","description":"Session token in Bearer format: Bearer <token>"}},"schemas":{"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"oneOf":[{"type":"string","description":"Error message"},{"type":"array","items":{"type":"object","required":["code","message","path"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"path":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"description":"Error path"}}}}]}}}}},"paths":{"/user/profile-image":{"delete":{"summary":"Remove user profile image","description":"Delete the profile image for the authenticated user","tags":["Authentication"],"responses":{"200":{"description":"Profile image removed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"description":"Unauthorized - invalid or missing session token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Upload user profile image

> Upload or replace the profile image for the authenticated user

```json
{"openapi":"3.0.0","info":{"title":"Meshmap API v1","version":"1.0.0"},"servers":[{"url":"/api/v1","description":"API v1 base URL"}],"security":[{"SessionToken":[]}],"components":{"securitySchemes":{"SessionToken":{"type":"apiKey","in":"header","name":"Authorization","description":"Session token in Bearer format: Bearer <token>"}},"schemas":{"UserSchema":{"type":"object","required":["id","createdAt"],"properties":{"id":{"type":"string","description":"Unique user identifier"},"email":{"type":"string","nullable":true,"description":"User email address"},"firstName":{"type":"string","nullable":true,"description":"User first name"},"lastName":{"type":"string","nullable":true,"description":"User last name"},"phoneNumber":{"type":"string","nullable":true,"description":"User phone number"},"username":{"type":"string","nullable":true,"description":"User username"},"createdAt":{"type":"string","format":"date-time","description":"User creation timestamp"},"imageUrl":{"type":"string","nullable":true,"description":"User profile image URL"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"oneOf":[{"type":"string","description":"Error message"},{"type":"array","items":{"type":"object","required":["code","message","path"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"path":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"description":"Error path"}}}}]}}}}},"paths":{"/user/profile-image":{"patch":{"summary":"Upload user profile image","description":"Upload or replace the profile image for the authenticated user","tags":["Authentication"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary","description":"Image file to upload"}}}}}},"responses":{"200":{"description":"Profile image uploaded successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}},"400":{"description":"Invalid image file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - invalid or missing session token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Generate authentication game code

> Generate a new 6-digit authentication code from headset side

```json
{"openapi":"3.0.0","info":{"title":"Meshmap API v1","version":"1.0.0"},"servers":[{"url":"/api/v1","description":"API v1 base URL"}],"security":[{"AppAPIKey":[]}],"components":{"securitySchemes":{"AppAPIKey":{"type":"apiKey","in":"header","name":"x-app-api-key","description":"App API key in format: <key>"}},"schemas":{"CreateCodeRequest":{"type":"object","required":["playerId"],"properties":{"playerId":{"type":"string","description":"Player ID to associate with the code. Used to link the player to the code. Optional.","nullable":true}}},"CodeSchema":{"type":"object","required":["code","expiryTime"],"properties":{"code":{"type":"string","description":"Generated authentication code","pattern":"^[0-9]{6}$"},"playerId":{"type":"string","nullable":true,"description":"Player ID associated with the code (if provided)"},"expiryTime":{"type":"string","format":"date-time","description":"Code expiration timestamp"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"oneOf":[{"type":"string","description":"Error message"},{"type":"array","items":{"type":"object","required":["code","message","path"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"path":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"description":"Error path"}}}}]}}}}},"paths":{"/code":{"post":{"summary":"Generate authentication game code","description":"Generate a new 6-digit authentication code from headset side","tags":["Authentication"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCodeRequest"}}}},"responses":{"200":{"description":"Code generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeSchema"}}}},"401":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unable to generate unique code or internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Validate authentication code

> Validate an authentication code and optionally return a session token

```json
{"openapi":"3.0.0","info":{"title":"Meshmap API v1","version":"1.0.0"},"servers":[{"url":"/api/v1","description":"API v1 base URL"}],"security":[{"AppAPIKey":[]}],"components":{"securitySchemes":{"AppAPIKey":{"type":"apiKey","in":"header","name":"x-app-api-key","description":"App API key in format: <key>"}},"schemas":{"CreateTokenFromCodeRequest":{"type":"object","required":["code"],"properties":{"code":{"type":"string","description":"Authentication code","pattern":"^[0-9]{6}$"}}},"CreateTokenFromCodeResponse":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["VALID","INVALID","EXPIRED","ERROR"],"description":"Code validation status"},"sessionToken":{"type":"string","description":"JWT session token (only present when status is VALID and user is authenticated)"},"expiryTime":{"type":"string","format":"date-time","description":"Code expiry time (only present when status is VALID)"},"error":{"type":"string","description":"Error message (only present when status is not VALID)"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"oneOf":[{"type":"string","description":"Error message"},{"type":"array","items":{"type":"object","required":["code","message","path"],"properties":{"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"},"path":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"number"}]},"description":"Error path"}}}}]}}}}},"paths":{"/auth/code":{"post":{"summary":"Validate authentication code","description":"Validate an authentication code and optionally return a session token","tags":["Authentication"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenFromCodeRequest"}}}},"responses":{"200":{"description":"Game code validation result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenFromCodeResponse"}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - invalid or missing App API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.meshmap.com/api/core/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
