Authenticate with Forage
Generate authentication and session tokens for Forage API requests.
To authenticate requests to the Forage API, you need bearer tokens: either an authentication token for server-side requests or a session token for client-side requests. Before you begin, register a Forage app to get your Client ID and Client Secret.
Not sure which token type you need? See Understanding Forage Authentication. For the full list of endpoints and SDK methods that require each type, see Authentication Token Reference.
Generate an authentication token
Server-side onlyGenerate authentication tokens server-side only. Never expose your Client ID or Client Secret to the client.
To generate an authentication token:
- Retrieve your app's Client ID and Client Secret from the Forage dashboard (sandbox, production). If you need help finding these credentials, then refer to the Register an app guide.
- Send a POST request to the
/o/tokenendpoint.
Encode your credentials:
Pass the Client ID and Client Secret separated by a colon, as in <client_id>:<client_secret>, through a base64 encoding function:
$ node
> btoa('<client-id>:<client-secret>')import base64
def encode_to_base64(input_string):
encoded_bytes = base64.b64encode(input_string.encode('utf-8'))
encoded_string = encoded_bytes.decode('utf-8')
return encoded_string
encoded_string = encode_to_base64('<client-id>:<client-secret>')
print(encoded_string)Send the request:
Pass the encoded result in the Authorization header after the word Basic, like Basic <encoded_credentials>:
Choosing a scopeThe
scopeparameter controls what the token can access. Usepinpad_onlyfor SDK-based integrations (most integrations). Usehosted_checkoutfor Fully Hosted Checkout integrations. Usereportingto query/reporting/endpoints. You can combine scopes with a space, for examplehosted_checkout reporting.
curl --request POST \
--url https://api.sandbox.joinforage.app/o/token/ \
--header 'Accept: application/json' \
--header 'Authorization: Basic <base64-encoded-client-id-secret-pair>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=pinpad_only' \
--data-urlencode 'expiration_time=1728000'import requests
response = requests.post(
"https://api.sandbox.joinforage.app/o/token/",
headers={
"Accept": "application/json",
"Authorization": "Basic <base64-encoded-client-id-secret-pair>",
"Content-Type": "application/x-www-form-urlencoded",
},
data={
"grant_type": "client_credentials",
"scope": "pinpad_only",
"expiration_time": "1728000",
},
)
print(response.json())import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.joinforage.app/o/token/"))
.header("Accept", "application/json")
.header("Authorization", "Basic <base64-encoded-client-id-secret-pair>")
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(
"grant_type=client_credentials&scope=pinpad_only&expiration_time=1728000"))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());const response = await fetch(
"https://api.sandbox.joinforage.app/o/token/",
{
method: "POST",
headers: {
Accept: "application/json",
Authorization: "Basic <base64-encoded-client-id-secret-pair>",
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
grant_type: "client_credentials",
scope: "pinpad_only",
expiration_time: "1728000",
}),
}
);
const data = await response.json();
console.log(data);require 'net/http'
require 'json'
uri = URI("https://api.sandbox.joinforage.app/o/token/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request["Accept"] = "application/json"
request["Authorization"] = "Basic <base64-encoded-client-id-secret-pair>"
request["Content-Type"] = "application/x-www-form-urlencoded"
request.set_form_data(
"grant_type" => "client_credentials",
"scope" => "pinpad_only",
"expiration_time" => "1728000"
)
response = http.request(request)
puts JSON.parse(response.body)
curl shorthandIf you're using curl, you can alternatively add the flag
-u <client_id>:<client_secret>to your request instead of passing theAuthorizationheader.curl --request POST \ --url https://api.sandbox.joinforage.app/o/token/ \ --header 'Accept: application/json' \ -u '<client_id>:<client_secret>' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'scope=pinpad_only' \ --data-urlencode 'expiration_time=1728000'
- Retrieve the
access_tokenvalue from the response.
{
"access_token": "sandbox_uXpcGMAMs7hhbw9JifUuJlzUZS3zWD",
"expires_in": 1728000,
"token_type": "Bearer",
"scope": "pinpad_only"
}The access_token value is your authentication token. Pass it as the bearer token in requests. Your Authorization header would be Bearer <authentication_token>.
Refer to the /o/token reference documentation for endpoint details.
Generate a session token
To generate a session token:
- Generate a Forage authentication token.
- Send a POST request to the
/session_token/endpoint:- Pass the authentication token in the
Authorizationheader. - Pass the merchant's FNS number in the
Merchant-Accountheader. Ask the merchant for their FNS number if you don't already have it handy.
- Pass the authentication token in the
Send the request:
curl --request POST \
--url https://api.sandbox.joinforage.app/api/session_token/ \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <authentication-token>' \
--header 'Merchant-Account: <merchant-id>' \
--header 'Content-Type: application/x-www-form-urlencoded'import requests
response = requests.post(
"https://api.sandbox.joinforage.app/api/session_token/",
headers={
"Accept": "application/json",
"Authorization": "Bearer <authentication-token>",
"Merchant-Account": "<merchant-id>",
"Content-Type": "application/x-www-form-urlencoded",
},
)
print(response.json())import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.joinforage.app/api/session_token/"))
.header("Accept", "application/json")
.header("Authorization", "Bearer <authentication-token>")
.header("Merchant-Account", "<merchant-id>")
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());const response = await fetch(
"https://api.sandbox.joinforage.app/api/session_token/",
{
method: "POST",
headers: {
Accept: "application/json",
Authorization: "Bearer <authentication-token>",
"Merchant-Account": "<merchant-id>",
"Content-Type": "application/x-www-form-urlencoded",
},
}
);
const data = await response.json();
console.log(data);require 'net/http'
require 'json'
uri = URI("https://api.sandbox.joinforage.app/api/session_token/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer <authentication-token>"
request["Merchant-Account"] = "<merchant-id>"
request["Content-Type"] = "application/x-www-form-urlencoded"
response = http.request(request)
puts JSON.parse(response.body)- Retrieve the
tokenvalue from the response.
{
"token": "sandbox_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}The token value is your session token. Pass it as the bearer token in API requests and as a parameter in SDK methods. Your Authorization header would be Bearer <session_token>.
Refer to the /session_token/ reference documentation for endpoint details.
Next steps
- Explore integration options to choose the right integration model for your project.
- Configure webhooks to receive event notifications for payments, refunds, and order updates.
Updated 4 days ago
