---
title: QuickStart Guide
slug: quickstart-guide
docTags: 
createdAt: 2025-07-08T09:09:30.421Z
---

## Service Details

The sandbox service can be reached at [mgmt-api.torogateway.dev](https://mgmt-api.torogateway.dev) . The production service will be at mgmt-api.torogateway.com.

You can test connectivity at [mgmt-api.torogateway.dev/v1/status](https://mgmt-api.torogateway.dev/v1/status) .

## OpenAPI/Swagger Documentation

The documentation is served as JSON at [mgmt-api.torogateway.dev/v1/doc](https://mgmt-api.torogateway.dev/v1/docs) and via a Swagger UI at [mgmt-api.torogateway.dev/v1/swagger-ui](https://mgmt-api.torogateway.dev/v1/swagger-ui). These endpoints are protected by Basic Auth, using the same password as this documentation and user `user`.

We recommend having the swagger documentation open while you run through this guide, to get a better idea of the options available to you.

## Your Account Details

An `account` has been created for you - the ID will be communicated separately.

An API key has been created with the permissions necessary to create `users`, `api_keys` and `roles` - the key will be communicated to you separately.

## Getting Started

You will first want to create either a new `user` or a new `api_key`with broader permissions.

To create a new API key:

1. Create a `role` with appropriate permissions.
2. Create the API key.

::::CodeDrawer{title="Create a Role" isResponseExpanded="true" autoGeneratedAnchorSlug="create-a-role" legacyHash="IcFv3s61TWNuOvAHVfPMb"}
:::CodeblockTabsExamples
```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/roles \
  -H "Content-Type: application/json" \
  -H "API-Key: <KEY>" \
  -d '{
    "name": "Admin",
		"description": "Full access to everything",
		"permissions": [
			"account_memberships:create",
			"account_memberships:delete",
			"account_memberships:read",
			"account_memberships:update",
			"api_keys:create",
			"api_keys:delete",
			"api_keys:read",
			"api_keys:update",
			"roles:create",
			"roles:delete",
			"roles:read",
			"roles:update",
			"users:create",
			"users:delete",
			"users:read",
			"users:update",
			"webhook_endpoints:create",
			"webhook_endpoints:delete",
			"webhook_endpoints:read",
			"webhook_endpoints:update",
			"messages:read",
			"receipts:read",
			"merchant_groups:create",
			"merchant_groups:delete",
			"merchant_groups:read",
			"merchant_groups:update",
			"merchants:create",
			"merchants:delete",
			"merchants:read",
			"merchants:update",
			"poi_groups:create",
			"poi_groups:delete",
			"poi_groups:read",
			"poi_groups:update",
			"pois:create",
			"pois:delete",
			"pois:read",
			"pois:update",
			"configurations_public:read",
			"configurations_public:update",
			"configurations_public:create",
			"configurations_public:delete"
		]
  }'
  
  # Note: it's not ideal to have an 'admin' account - you can limit
  # the scope for problems by having more limited roles; a user can have
  # multiple `account_memberships` in a single account with different roles,
  # giving more granular control over an individual's permissions.
```
:::

:::CodeblockTabsResponses
```javascript
{
    "id": "rol_new",
		"name": "Admin",
    "account_id": "acc_123abc",
    "creator_id": "apk_54321zyxwv", // the ID of the API key or user that created the Role
    "description": "Full administrative access to everything",
		"permissions": [
			"account_memberships:create",
			"account_memberships:delete",
			"account_memberships:read",
			"account_memberships:update",
			"api_keys:create",
			"api_keys:delete",
			"api_keys:read",
			"api_keys:update",
			"roles:create",
			"roles:delete",
			"roles:read",
			"roles:update",
			"users:create",
			"users:delete",
			"users:read",
			"users:update",
			"webhook_endpoints:create",
			"webhook_endpoints:delete",
			"webhook_endpoints:read",
			"webhook_endpoints:update",
			"messages:read",
			"receipts:read",
			"merchant_groups:create",
			"merchant_groups:delete",
			"merchant_groups:read",
			"merchant_groups:update",
			"merchants:create",
			"merchants:delete",
			"merchants:read",
			"merchants:update",
			"poi_groups:create",
			"poi_groups:delete",
			"poi_groups:read",
			"poi_groups:update",
			"pois:create",
			"pois:delete",
			"pois:read",
			"pois:update",
			"configurations_public:read",
			"configurations_public:update",
			"configurations_public:create",
			"configurations_public:delete"
		],
    "created_at": "2025-01-01T00:00:00",
    "updated_at": "2025-01-01T00:00:00"
}
```
:::
::::

::::CodeDrawer{title="Create an API Key" isResponseExpanded="true" autoGeneratedAnchorSlug="create-an-api-key" legacyHash="1696zw5fZb3Gw8WpFyrLk"}
:::CodeblockTabsExamples
```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/api-keys \
  -H "Content-Type: application/json" \
  -H "API-Key: <KEY>" \
  -d '{
    "name": "Admin Test",
    "description": "API key with admin permissions for testing purposes",
    "role_id": "<ID>",
    "expires_at": "2026-01-01 00:00"
  }'
  
  # Note: the date field should be RFC 9557 compliant and not include a
  # timezone. This may be made more flexible in future.
```
:::

:::CodeblockTabsResponses
```javascript
{
    "id": "apik_new",
    "account_id": "acc_123abc",
    "identifier": "1234567890",
    "last_used_at": "2025-01-01T00:00Z",
    "created_at": "2025-01-01T00:00Z",
    "updated_at": "2025-01-01T00:00Z",
    "key": "xyz098abc123"
}
```
:::
::::

To create a new user:

1. Create a `user`. NB email address need to be unique. This will return a password, which you should make a note of (a more robust password creation flow will be implemented later, so please don't rely on this for automation).
2. Create a `role` with appropriate permissions (as above).
3. Create an `account membership` linking the user to your account and giving it the new `role`.

::::CodeDrawer{title="Create a User" isResponseExpanded="true" autoGeneratedAnchorSlug="create-a-user" legacyHash="2pyftYAxTSI2EK9xjq0f0"}
:::CodeblockTabsExamples
```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/users \
  -H "Content-Type: application/json" \
  -H "API-Key: <KEY>" \
  -d '{
    "email": "example@email.com",
    "name": "Jane Doe",
    "is_active": true
  }'
  
  # Email addresses must be unique.
```
:::

:::CodeblockTabsResponses
```javascript
{
    "id": "usr_newrandomid",
    "email": "example@email.com",
    "name": "Jane Doe",
    "is_active": true,
    "created_at": "2025-01-01T00:00Z",
    "updated_at": "2025-01-01T00:00Z",
    "password": "random_password"
}
# NB the 'password' property is only being
# returned as a temporary measure, until
# a more robust system can be developed.
```
:::
::::

::::CodeDrawer{title="Grant a Role in an Account to a User" isResponseExpanded="true" autoGeneratedAnchorSlug="grant-a-role-in-an-account-to-a-user" legacyHash="RpbMZlh8h2joE901MCmBr"}
:::CodeblockTabsExamples
```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/accounts/:acc_id/memberships \
	-H "Content-Type: application/json" \
  -H "API-Key: <KEY>" \
  -d '{
		"user_id": "<ID>",
		"role_id": "<ID>"
	}'
```
:::

:::CodeblockTabsResponses
```javascript
{
	"id": "acm_new",
	"account_id": "acc_abc123",
	"user_id": "usr_12345abcde",
	"role_id": "rol_98765abcde",
	"invitation_id": null,
	"creator_id": "apik_someid",
	"created_at": "2023-01-01T00:00:00Z",
	"updated_at": "2023-01-01T00:00:00Z"
}
```
:::
::::

You now have full access to the API. In order to process transactions, you will need a POI (Point Of Interaction) linked to a Merchant.

### Merchants and POIs

To set up an end user to be able to process transactions, we need to have a record of their POI (Point of Interaction - e.g. card payment terminal or softpos installation) linked to a 'merchant'.

A merchant represents a single legal entity that has a direct transactional relationship with customers (e.g. with a fleet of self-employed taxi drivers you might have one per driver, but as a chain of supermarkets you might have just one merchant).

::::CodeDrawer{title="Create a Merchant" isResponseExpanded="true" autoGeneratedAnchorSlug="create-a-merchant" legacyHash="luOcu7AHb_B7hQ-S_nIps"}
:::CodeblockTabsExamples
```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/merchants \
	-H "Content-Type: application/json" \
	-H "API-Key: <KEY>" \
	-d '{
	    "legal_name": "Test Merchant",
	    "address": {
	        "account_id": <ID>,
            "line_1": "1 Some Street",
            "city": "London"
        },
		"configuration_id": <ID>,
		"merchant_group_id": null,
		"is_active": true
	}'
# Note 1: instead of the `address` parameter you can provide the ID of an
# existing address as `address_id`.
```
:::

:::CodeblockTabsResponses
```javascript
{
	"id": "mer_new",
	"account_id": "acc_123abc",
	"legal_name": "Test Merchant",
	"address_id": "addr_new",
	"configuration_id": null,
	"merchant_group_id": null,
	"is_active": true,
}
```
:::
::::

::::CodeDrawer{title="Create a POI" isResponseExpanded="true" autoGeneratedAnchorSlug="create-a-poi" legacyHash="jZe11pX3dHyBB3iEATDnt"}
:::CodeblockTabsExamples
```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/pois \
	-H "Content-Type: application/json" \
	-H "API-Key: <KEY>" \
	-d '{
		"manufacturer_id": "<STRING>",
		"label_id": "<STRING>",
		"model_id": "miura_m21",
		"model_version": "TEST01-V3-4",
		"merchant_id": "<ID>",
		"configuration_id": "<ID>",
		"poi_group_id": null,
		"is_active": true
	}'
# Note 1: as we need to supply specific details to the acquirer banks,
# and our certifications are model-specific, POI `models` need to be set up
# by our team. An API endpoint for listing available/supported models
# will be added soon. For now please just use the model_id and model_version
# provided above.

# Note 2: the `manufacturer_id` is the ID assigned by the manufacturer,
# most commonly referred to as a serial number. It must be the value that
# will be returned by the terminal's firmware when queried (returned by 
# GetDeviceInfo in our SDK).

# Note 3: `label_id` can be any string you like, but is intended to be used
# for the ID phisically printed on the device (typically on a sticker)

# Note 3: the `label_id` is simply whatever is written on the physical device.
# This field is just for convenience when IDing your inventory.
```
:::

:::CodeblockTabsResponses
```javascript
{
	"id": "poi_new",
	"account_id": "acc_123abc",
	"manufacturer_id": "21100222",
	"label_id": "021-100222",
	"model_id": "tmp_12345abcde",
	"model_version": "TEST01-V3-4",
	"merchant_id": "mer_new",
	"configuration_id": null,
	"poi_group_id": null,
	"is_active": true,
	"created_at": "2025-01-01T00:00:00",
	"updated_at": "2025-01-01T00:00:00"
}
```
:::
::::

Note that we set `configuration_id` to `null` for both of these. In the sandbox environment we've set up account-wide default configurations with enough details to get you going.

At this point you're ready to process transactions! Transactions processed on your POIs can now be processed, using the `manufacturer_id` field (the ID returned by the terminal's firmware)  to link them to your account. No changes need to be made on the client/SDK side to enable this.

## Next Steps

### Less-privileged users

You will probably want to create less-privileged users. Simply create new roles with appropriate permissions. For example:

```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/roles \
  -H "Content-Type: application/json" \
  -H "API-Key: <KEY>" \
  -d '{
    "name": "Taxi Driver",
	"description": "Read-only access to finalised transactions",
	"permissions": [
		"receipts:read"
	]
  }'
```

A user with this role will have access to their own user details and to the `/v1/receipts` endpoints, which will return basic details of completed transactions (financially captured or failed).

### User authentication

In out examples we've used an API key, but we also support Bearer Authentication (which we expect to be more useful for e.g. end-user dashboards). We use the refresh token pattern - if you've never worked with this auth0.com has a useful primer ([link](https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/)). In our system we have three types of token: `user_refresh` tokens, which are the long-lived refresh token, `user_access` tokens, which are access tokens allowing a user to access and update their own user details but nothing else in the account, and `role_access` tokens which grant access to resources account-wide based on the `role`'s permissions.

Note that user can only access a `role` they are linked to via an `account_membership` - see the relevant section above for how to set this up. A user can have many memberships in a single account, so you might for example have an 'Accounts' role with access only to transaction history (the `receipts:read` permission) and a 'Driver Support' role with a range of permissions to allow them to create and update `merchants` and allocate `pois` to them, and a single user could access either of these roles with the same credentials.

### Get Transactions

Finalised transactions can be retrieved at the `/v1/receipts` endpoint. See the Swagger documentation for available filters.

::::CodeDrawer{title="List Receipts" isResponseExpanded="true" autoGeneratedAnchorSlug="list-receipts" legacyHash="6s8v7z-QQYYFQ2XbJ2xl2"}
:::CodeblockTabsExamples
```curl
curl -X GET https://mgmt-api.torogateway.dev/v1/receipts \
	-H "Content-Type: application/json" \
	-H "API-Key: <KEY>"
```
:::

:::CodeblockTabsResponses
```javascript
```
:::
::::

### Merchant and POI Groups

POIs and Merchants can be grouped. This is useful for two purposes: you can filter by group, and you can attach a configuration to a whole group. One use-case for this is to apply different trading names to different parts of your fleet.

::::CodeDrawer{title="Create a POI Group" isResponseExpanded="true" autoGeneratedAnchorSlug="create-a-poi-group" legacyHash="xawsCc6XXFSLGkWXOBKG_"}
:::CodeblockTabsExamples
```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/poi-groups \
	-H "Content-Type: application/json" \
	-H "API-Key: <KEY>" \
	-d '{
		"parent_group_id": null,
		"configuration_id": null
	}'

# Note: the way configurations work for nested pois/groups is that the child 
# overrides the parent. E.g. if you have a poi with config 
# `{foo: true, bar: null}` and it belongs to a poi group with config
# `{foo: false, bar: false}` the final config will be `{foo: true, bar: false}`
```
:::

:::CodeblockTabsResponses
```javascript
{
    "id": "poig_new",
    "account_id": "acc_123abc",
    "parent_group_id": null,
    "configuration_id": null,
    "created_at": "2025-01-01T00:00Z",
    "updated_at": "2025-01-01T00:00Z"
}
```
:::
::::

::::CodeDrawer{title="Add a POI to a Group" isResponseExpanded="true" autoGeneratedAnchorSlug="add-a-poi-to-a-group" legacyHash="x12XNa3asj5tutksQsxfJ"}
:::CodeblockTabsExamples
```curl
curl -X POST https://mgmt-api.torogateway.dev/v1/poi-groups/:group_id/pois \
	-H "Content-Type: application/json" \
	-H "API-Key: <KEY>" \
	-d '{
		"poi_id": "<ID>"
	}'
```
:::

:::CodeblockTabsResponses
```javascript
{
    poi_id: "poi_new",
    group_id: "poig_12345abcde"
}
```
:::
::::

Creating and updating a merchant group works exactly the same.

NB you can't mix-and-match groups; merchants and merchant groups can only belong to merchant groups, and POIs and POI groups can only belong to POI groups.

### Configuration

In the sandbox environment we've set up account-wide default configurations with enough details to get you going, but to get production-ready you'll need to be able to configure POIs or parts of your POI estate separately.

We have a flexible configuration system that lets you set the same configuration options on a POI, Merchant, POI Group, or Merchant Group.

Important values include the 'Doing Business As' name that will be set on transactions, and any acquirer-specific configuration. There are also configuration options that can only be set by administrators, like whether transactions should be captured with the authorisation request or in a completion message.

Please see the Configuration chapter in the documentation for full details.
