> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.mercoa.com/embedded-ap-ar/home/common-concepts/jwt-tokens/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.mercoa.com/_mcp/server. # JWT Authentication > Learn how Mercoa uses JWT tokens for frontend authentication, including token creation, revocation, and session management. Mercoa uses JSON Web Tokens (JWTs) for frontend authentication. JWTs provide a secure and efficient way to authenticate users and control access to the Mercoa platform. ## JWT Creation JWTs can be created at multiple levels within your organization: ### Entity Level ### Request POST [https://api.mercoa.com/entity/\{entityId}/token](https://api.mercoa.com/entity/\{entityId}/token) **`Default`** ```curl Default curl -X POST https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "expiresIn": "1h" }' ``` **`Default`** ```python Default import requests url = "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token" payload = { "expiresIn": "1h" } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` **`Default`** ```typescript Default import { MercoaClient } from "@mercoa/javascript"; const client = new MercoaClient({ token: "YOUR_TOKEN" }); await client.entity.getToken("ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced", { expiresIn: "1h" }); ``` **`Default`** ```go Default package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token" payload := strings.NewReader("{\n \"expiresIn\": \"1h\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") 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)) } ``` **`Default`** ```ruby Default require 'uri' require 'net/http' url = URI("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"expiresIn\": \"1h\"\n}" response = http.request(request) puts response.read_body ``` **`Default`** ```java Default import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"expiresIn\": \"1h\"\n}") .asString(); ``` **`Default`** ```php Default request('POST', 'https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token', [ 'body' => '{ "expiresIn": "1h" }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` **`Default`** ```csharp Default using RestSharp; var client = new RestClient("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"expiresIn\": \"1h\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` **`Default`** ```swift Default import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = ["expiresIn": "1h"] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token")! 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() ``` ### Entity User Level ### Request POST [https://api.mercoa.com/entity/\{entityId}/user/\{userId}/token](https://api.mercoa.com/entity/\{entityId}/user/\{userId}/token) **`Default`** ```curl Default curl -X POST https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/user_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "expiresIn": "1h" }' ``` **`Default`** ```python Default import requests url = "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/user_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token" payload = { "expiresIn": "1h" } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` **`Default`** ```typescript Default import { MercoaClient } from "@mercoa/javascript"; const client = new MercoaClient({ token: "YOUR_TOKEN" }); await client.entity.user.getToken("ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced", "user_a0f6ea94-0761-4a5e-a416-3c453cb7eced", { expiresIn: "1h" }); ``` **`Default`** ```go Default package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/user_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token" payload := strings.NewReader("{\n \"expiresIn\": \"1h\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") 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)) } ``` **`Default`** ```ruby Default require 'uri' require 'net/http' url = URI("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/user_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"expiresIn\": \"1h\"\n}" response = http.request(request) puts response.read_body ``` **`Default`** ```java Default import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/user_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"expiresIn\": \"1h\"\n}") .asString(); ``` **`Default`** ```php Default request('POST', 'https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/user_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token', [ 'body' => '{ "expiresIn": "1h" }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` **`Default`** ```csharp Default using RestSharp; var client = new RestClient("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/user_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"expiresIn\": \"1h\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` **`Default`** ```swift Default import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = ["expiresIn": "1h"] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/user_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token")! 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() ``` ### Entity Group Level ### Request POST [https://api.mercoa.com/entityGroup/\{entityGroupId}/token](https://api.mercoa.com/entityGroup/\{entityGroupId}/token) **`Default`** ```curl Default curl -X POST https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "expiresIn": "1h" }' ``` **`Default`** ```python Default import requests url = "https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token" payload = { "expiresIn": "1h" } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` **`Default`** ```typescript Default import { MercoaClient } from "@mercoa/javascript"; const client = new MercoaClient({ token: "YOUR_TOKEN" }); await client.entityGroup.getToken("entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced", { expiresIn: "1h" }); ``` **`Default`** ```go Default package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token" payload := strings.NewReader("{\n \"expiresIn\": \"1h\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") 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)) } ``` **`Default`** ```ruby Default require 'uri' require 'net/http' url = URI("https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"expiresIn\": \"1h\"\n}" response = http.request(request) puts response.read_body ``` **`Default`** ```java Default import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"expiresIn\": \"1h\"\n}") .asString(); ``` **`Default`** ```php Default request('POST', 'https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token', [ 'body' => '{ "expiresIn": "1h" }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` **`Default`** ```csharp Default using RestSharp; var client = new RestClient("https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"expiresIn\": \"1h\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` **`Default`** ```swift Default import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = ["expiresIn": "1h"] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token")! 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() ``` ### Entity Group User Level ### Request POST [https://api.mercoa.com/entityGroup/\{entityGroupId}/user/\{foreignId}/token](https://api.mercoa.com/entityGroup/\{entityGroupId}/user/\{foreignId}/token) **`Default`** ```curl Default curl -X POST https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/MY-DB-ID-12345/token \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "expiresIn": "1h" }' ``` **`Default`** ```python Default import requests url = "https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/MY-DB-ID-12345/token" payload = { "expiresIn": "1h" } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` **`Default`** ```typescript Default import { MercoaClient } from "@mercoa/javascript"; const client = new MercoaClient({ token: "YOUR_TOKEN" }); await client.entityGroup.user.getToken("entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced", "MY-DB-ID-12345", { expiresIn: "1h" }); ``` **`Default`** ```go Default package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/MY-DB-ID-12345/token" payload := strings.NewReader("{\n \"expiresIn\": \"1h\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") 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)) } ``` **`Default`** ```ruby Default require 'uri' require 'net/http' url = URI("https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/MY-DB-ID-12345/token") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"expiresIn\": \"1h\"\n}" response = http.request(request) puts response.read_body ``` **`Default`** ```java Default import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/MY-DB-ID-12345/token") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"expiresIn\": \"1h\"\n}") .asString(); ``` **`Default`** ```php Default request('POST', 'https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/MY-DB-ID-12345/token', [ 'body' => '{ "expiresIn": "1h" }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` **`Default`** ```csharp Default using RestSharp; var client = new RestClient("https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/MY-DB-ID-12345/token"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"expiresIn\": \"1h\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` **`Default`** ```swift Default import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = ["expiresIn": "1h"] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/entityGroup/entg_a0f6ea94-0761-4a5e-a416-3c453cb7eced/user/MY-DB-ID-12345/token")! 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() ``` ## Token Revocation All JWTs can be revoked at the organization level using the `invalidateTokens` endpoint: ### Request POST [https://api.mercoa.com/organization/invalidateTokens](https://api.mercoa.com/organization/invalidateTokens) **`All Sessions`** ```curl All Sessions curl -X POST https://api.mercoa.com/organization/invalidateTokens \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "sessionId": null }' ``` **`All Sessions`** ```python All Sessions import requests url = "https://api.mercoa.com/organization/invalidateTokens" payload = { "sessionId": None } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` **`All Sessions`** ```typescript All Sessions import { MercoaClient } from "@mercoa/javascript"; const client = new MercoaClient({ token: "YOUR_TOKEN" }); await client.organization.invalidateTokens(); ``` **`All Sessions`** ```go All Sessions package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.mercoa.com/organization/invalidateTokens" payload := strings.NewReader("{\n \"sessionId\": null\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") 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)) } ``` **`All Sessions`** ```ruby All Sessions require 'uri' require 'net/http' url = URI("https://api.mercoa.com/organization/invalidateTokens") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"sessionId\": null\n}" response = http.request(request) puts response.read_body ``` **`All Sessions`** ```java All Sessions import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.mercoa.com/organization/invalidateTokens") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"sessionId\": null\n}") .asString(); ``` **`All Sessions`** ```php All Sessions request('POST', 'https://api.mercoa.com/organization/invalidateTokens', [ 'body' => '{ "sessionId": null }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` **`All Sessions`** ```csharp All Sessions using RestSharp; var client = new RestClient("https://api.mercoa.com/organization/invalidateTokens"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"sessionId\": null\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` **`All Sessions`** ```swift All Sessions import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = ["sessionId": ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/organization/invalidateTokens")! 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() ``` ## Session Management JWTs can be created with a session ID, which is controlled by the platform. This allows for more granular control over token lifecycle: ### Request POST [https://api.mercoa.com/entity/\{entityId}/token](https://api.mercoa.com/entity/\{entityId}/token) **`SessionID`** ```curl SessionID curl -X POST https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "expiresIn": "1h", "sessionId": "session_123" }' ``` **`SessionID`** ```python SessionID import requests url = "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token" payload = { "expiresIn": "1h", "sessionId": "session_123" } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` **`SessionID`** ```typescript SessionID import { MercoaClient } from "@mercoa/javascript"; const client = new MercoaClient({ token: "YOUR_TOKEN" }); await client.entity.getToken("ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced", { expiresIn: "1h", sessionId: "session_123" }); ``` **`SessionID`** ```go SessionID package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token" payload := strings.NewReader("{\n \"expiresIn\": \"1h\",\n \"sessionId\": \"session_123\"\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") 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)) } ``` **`SessionID`** ```ruby SessionID require 'uri' require 'net/http' url = URI("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"expiresIn\": \"1h\",\n \"sessionId\": \"session_123\"\n}" response = http.request(request) puts response.read_body ``` **`SessionID`** ```java SessionID import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"expiresIn\": \"1h\",\n \"sessionId\": \"session_123\"\n}") .asString(); ``` **`SessionID`** ```php SessionID request('POST', 'https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token', [ 'body' => '{ "expiresIn": "1h", "sessionId": "session_123" }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` **`SessionID`** ```csharp SessionID using RestSharp; var client = new RestClient("https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"expiresIn\": \"1h\",\n \"sessionId\": \"session_123\"\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` **`SessionID`** ```swift SessionID import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = [ "expiresIn": "1h", "sessionId": "session_123" ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/entity/ent_a0f6ea94-0761-4a5e-a416-3c453cb7eced/token")! 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() ``` Sessions will automatically be invalidated if a new token for that session is not created within 24 hours. This time limit is subject to change. To revoke tokens for a specific sessions: ### Request POST [https://api.mercoa.com/organization/invalidateTokens](https://api.mercoa.com/organization/invalidateTokens) **`Sessions`** ```curl Sessions curl -X POST https://api.mercoa.com/organization/invalidateTokens \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "sessionId": [ "session_123", "session_456" ] }' ``` **`Sessions`** ```python Sessions import requests url = "https://api.mercoa.com/organization/invalidateTokens" payload = { "sessionId": ["session_123", "session_456"] } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` **`Sessions`** ```typescript Sessions import { MercoaClient } from "@mercoa/javascript"; const client = new MercoaClient({ token: "YOUR_TOKEN" }); await client.organization.invalidateTokens({ sessionId: ["session_123", "session_456"] }); ``` **`Sessions`** ```go Sessions package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://api.mercoa.com/organization/invalidateTokens" payload := strings.NewReader("{\n \"sessionId\": [\n \"session_123\",\n \"session_456\"\n ]\n}") req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Authorization", "Bearer ") 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)) } ``` **`Sessions`** ```ruby Sessions require 'uri' require 'net/http' url = URI("https://api.mercoa.com/organization/invalidateTokens") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Post.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"sessionId\": [\n \"session_123\",\n \"session_456\"\n ]\n}" response = http.request(request) puts response.read_body ``` **`Sessions`** ```java Sessions import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.post("https://api.mercoa.com/organization/invalidateTokens") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"sessionId\": [\n \"session_123\",\n \"session_456\"\n ]\n}") .asString(); ``` **`Sessions`** ```php Sessions request('POST', 'https://api.mercoa.com/organization/invalidateTokens', [ 'body' => '{ "sessionId": [ "session_123", "session_456" ] }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` **`Sessions`** ```csharp Sessions using RestSharp; var client = new RestClient("https://api.mercoa.com/organization/invalidateTokens"); var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"sessionId\": [\n \"session_123\",\n \"session_456\"\n ]\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` **`Sessions`** ```swift Sessions import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = ["sessionId": ["session_123", "session_456"]] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/organization/invalidateTokens")! 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() ``` ## Role-Based Access Control JWTs work in conjunction with Mercoa's Role-Based Access Control (RBAC) system. The roles and permissions assigned to a user are encoded in the JWT, ensuring that users can only access the resources and perform the actions they are authorized for. For more information about roles and permissions, see our [RBAC documentation](/common-concepts/rbac). ## Best Practices 1. **Token Expiration**: Set appropriate expiration times for your JWTs based on your security requirements. Shorter expiration times are generally more secure. 2. **Session Management**: Use session IDs when you need to track and manage user sessions, especially for features like "logout everywhere" or session invalidation. 3. **Token Storage**: Store JWTs securely in your frontend application or not at all. Consider using secure HTTP-only cookies or secure local storage mechanisms. 4. **Token Refresh**: Implement a token refresh mechanism for long-lived sessions to maintain security while providing a good user experience. > Learn how Mercoa uses JWT tokens for frontend authentication, including token creation, revocation, and session management.