Skip to main content
This guide walks you through everything you need to go from zero to a working Portal.io API request. By the end, you will have a sandbox account, valid credentials, and a confirmed API response.
You can also explore the API interactively using the official Postman collection. Click Run in Postman or import the collection directly: https://god.gw.postman.com/run-collection/22981260-7030cfc9-3a53-4f6a-b4b9-0560e8514aec
1

Sign up for a sandbox account

Go to https://sandbox.portal.io and create a free sandbox dealer account. This account represents a test dealership and is the identity you will use when exchanging credentials and interacting with the sandbox API.Verify your email address before proceeding — unverified accounts cannot authenticate.
2

Get your API Application Key and Secret Key

After you have a sandbox account, contact your Portal.io representative and let them know. They will provide two values:
  • API Application Key — a UUID that identifies your integration, sent as the X-MSS-API-APPID header on every request.
  • Secret Key — a Base64-encoded string used as the raw key material when computing your HMAC-SHA256 request signatures. Keep this value secret.
You cannot proceed to the next step without both of these credentials.
3

Exchange your credentials for a User API Key

Call GET /authenticate/apikeyexchange with your Portal.io username and password as query parameters, along with the required HMAC authentication headers. A successful response returns a JSON object; the value at meta.apiKey is your User API Key.
For this initial credential exchange, the X-MSS-API-USERKEY header must be an empty string and is excluded from the HMAC canonical message. Do not include a User Key value here — you are exchanging your username and password to obtain one.
curl -i -X GET \
  "https://sandbox.api.portal.io/authenticate/apikeyexchange?UserName=user%40example.com&Password=MyP%40ss123" \
  -H "Accept: application/json" \
  -H "X-MSS-API-APPID: YOUR_APP_ID" \
  -H "X-MSS-API-USERKEY: " \
  -H "X-MSS-CUSTOM-DATE: Mon, 06 Apr 2026 00:22:19 GMT" \
  -H "X-MSS-SIGNATURE: BASE64_HMAC_SIGNATURE"
Replace YOUR_APP_ID with your API Application Key and BASE64_HMAC_SIGNATURE with the HMAC-SHA256 signature you computed for this request. See Signing requests for how to compute the signature.A 200 response includes the User API Key in the response body:
{
  "meta": {
    "apiKey": "qBOSOYDeZaSzTxqMCL1Kr66JpU2H6wHCLz7xviZUOcA="
  }
}
Store this value — you will send it as X-MSS-API-USERKEY on all subsequent requests.
4

Include your User API Key on all subsequent requests

Every authenticated API call requires the User Key you obtained in the previous step. Include it as the X-MSS-API-USERKEY header, and also incorporate its exact value into your HMAC canonical message when computing the signature for each request.The four required auth headers on every authenticated request are:
HeaderValue
X-MSS-API-APPIDYour API Application Key
X-MSS-API-USERKEYThe User Key from the exchange
X-MSS-CUSTOM-DATECurrent UTC timestamp in RFC 7231 format
X-MSS-SIGNATUREHMAC-SHA256 signature, Base64 encoded
5

Make a test request

With your credentials in place, confirm everything is working by listing your proposals. A 200 response with a proposals array means you are fully set up.
curl -i -X GET \
  "https://sandbox.api.portal.io/public/proposals" \
  -H "Accept: application/json" \
  -H "X-MSS-API-APPID: YOUR_APP_ID" \
  -H "X-MSS-API-USERKEY: YOUR_USER_KEY" \
  -H "X-MSS-CUSTOM-DATE: Mon, 06 Apr 2026 00:22:19 GMT" \
  -H "X-MSS-SIGNATURE: BASE64_HMAC_SIGNATURE"
If you receive a 401, double-check that your signature was computed correctly and that your X-MSS-CUSTOM-DATE timestamp exactly matches the value used in the canonical message. See authentication errors for more detail.