Skip to main content

Getting Started

Three calls and you are reading live data: get a token, find the plugin instance, call the module. This page is those three, with code you can paste.

1. Base URL​

The API lives on your eConnect server, under /api/v2.

DeploymentBase URL
On-premisehttps://<your-server>/api/v2
Cloudhttps://<customer>.econnectcloud.com/api/v2

Every path in this guide is appended to that. All traffic is HTTPS; the server will not accept tokens over plain HTTP.

Generate a client instead of hand-rolling one

The server publishes an OpenAPI 3.0 document covering all 688 endpoints. On a development build it is at /swagger/v2/swagger.json, with Swagger UI at /swagger. Point openapi-generator, NSwag or kiota at it and you get a typed client for nothing.

Swagger is not served on production builds. Take the document from a development or staging server, or ask eConnect for the schema that matches your version.

2. Get a token​

POST /api/v2/auth/login exchanges a username and password for a token pair.

curl -X POST https://your-server/api/v2/auth/login \
-H 'Content-Type: application/json' \
-d '{ "userName": "integration-svc", "password": "••••••••" }'
{
"accessToken": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "9f2c1e8a4b7d...",
"expiresInSeconds": 900
}

The access token is a compact ES256 JWT with a ~15 minute life. Send it on every other call:

Authorization: Bearer eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...

The refresh token is opaque, rotates on each use, and is bound to the session behind it.

Use a service account, not a person

Give the integration its own eConnect user with only the permission keys it needs. A token carries that user's rights, so a service account is how you bound what an integration can reach — and it survives the person who set it up leaving.

Signing in with an access id​

Unattended integrations can use a static access id instead of a password:

curl -X POST https://your-server/api/v2/auth/login/access-id \
-H 'Content-Type: application/json' \
-d '{ "accessId": "3b7f5c2e-9a41-4d8b-bb0e-7c1a2d3e4f50" }'

The access id is a credential: treat it exactly as you would a password.

Refreshing​

When the access token expires, exchange the refresh token for a new pair. Do not re-run login on a timer — that creates a session every time.

curl -X POST https://your-server/api/v2/auth/token/refresh \
-H 'Content-Type: application/json' \
-d '{ "refreshToken": "9f2c1e8a4b7d..." }'

A refresh token can be used once: the response carries the next one. If a refresh is rejected, sign in again.

EndpointPurpose
POST /auth/loginUsername and password for a token pair
POST /auth/login/access-idStatic access id for a token pair
POST /auth/token/refreshRotate the refresh token for a new pair
POST /auth/logoutEnd the session behind the bearer token
PUT /auth/session/groupSwitch the session's user group; returns a fresh pair
GET /.well-known/econnect/jwks.jsonPublic keys, to verify tokens yourself

3. Find the plugin instance​

Most endpoints belong to a plugin instance rather than to the server. List what this deployment has:

curl https://your-server/api/v2/portal/installed-plugins \
-H "Authorization: Bearer $ACCESS_TOKEN"
[
{
"pluginInstalledID": "8f6a1c54-0e2b-4a8e-9f10-2d3c4b5a6e70",
"name": "Casino – Main Floor",
"pluginID": "CASINOCONNECT",
"userGroupID": "1c0de2a4-f8b9-4e2a-9b77-d3f1b6a05c4e"
},
{
"pluginInstalledID": "722939ea-86af-486e-a3f7-ec0e0c4ddf6b",
"name": "Point of Sale",
"pluginID": "POSDATAEVENTS"
}
]

You only see the instances your user is permitted to see. Match on pluginID for the module type and keep pluginInstalledID — it goes in the path of every call to that module.

Do not hard-code the id

Instance ids differ per deployment, and a customer can add a second instance at any time. Look them up at start-up and cache them for the life of the process.

4. Call the module​

Now the real work. Reading the most recent point-of-sale events:

curl "https://your-server/api/v2/pos/plugins/722939ea-86af-486e-a3f7-ec0e0c4ddf6b/events?recordsPerPage=50&orderBy=DataTimeStamp%20desc" \
-H "Authorization: Bearer $ACCESS_TOKEN"

Pushing a TITO ticket into the casino module:

curl -X POST https://your-server/api/v2/casino-connect/plugins/8f6a1c54-0e2b-4a8e-9f10-2d3c4b5a6e70/tito-tickets \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"ticketBarcode": "TKT-00412887",
"ticketAmount": 125.50,
"dataTimeStamp": "2026-10-02T21:14:05Z",
"deviceId": "EGM-1042",
"transactionTypeDesc": "Redeem"
}'

The whole thing, in one file​

const BASE = 'https://your-server/api/v2';

async function signIn(userName, password) {
const res = await fetch(`${BASE}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userName, password }),
});
if (!res.ok) throw new Error(`sign-in failed: ${res.status}`);
return res.json(); // { accessToken, refreshToken, expiresInSeconds }
}

async function findPlugin(token, pluginId) {
const res = await fetch(`${BASE}/portal/installed-plugins`, {
headers: { Authorization: `Bearer ${token}` },
});
const plugins = await res.json();
const match = plugins.find((p) => p.pluginID === pluginId);
if (!match) throw new Error(`${pluginId} is not installed on this server`);
return match.pluginInstalledID;
}

async function pushTicket(token, instanceId, ticket) {
const res = await fetch(`${BASE}/casino-connect/plugins/${instanceId}/tito-tickets`, {
method: 'POST',
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify(ticket),
});
if (!res.ok) throw new Error(await res.text()); // ProblemDetails JSON
return res.json();
}

const { accessToken } = await signIn('integration-svc', process.env.EC_PASSWORD);
const casino = await findPlugin(accessToken, 'CASINOCONNECT');

await pushTicket(accessToken, casino, {
ticketBarcode: 'TKT-00412887',
ticketAmount: 125.5,
dataTimeStamp: new Date().toISOString(),
deviceId: 'EGM-1042',
transactionTypeDesc: 'Redeem',
});
using System.Net.Http.Json;

var http = new HttpClient { BaseAddress = new Uri("https://your-server/api/v2/") };

var tokens = await http.PostAsJsonAsync("auth/login", new { userName = "integration-svc", password = pw })
.Result.Content.ReadFromJsonAsync<TokenPair>();

http.DefaultRequestHeaders.Authorization = new("Bearer", tokens!.AccessToken);

var plugins = await http.GetFromJsonAsync<List<PluginInstalled>>("portal/installed-plugins");
var casino = plugins!.First(p => p.PluginID == "CASINOCONNECT").PluginInstalledID;

var response = await http.PostAsJsonAsync($"casino-connect/plugins/{casino}/tito-tickets", new
{
ticketBarcode = "TKT-00412887",
ticketAmount = 125.50m,
dataTimeStamp = DateTime.UtcNow,
deviceId = "EGM-1042",
transactionTypeDesc = "Redeem",
});
response.EnsureSuccessStatusCode();

record TokenPair(string AccessToken, string RefreshToken, int ExpiresInSeconds);
record PluginInstalled(Guid PluginInstalledID, string Name, string PluginID);

Next​