curl --request POST \
--url https://api.ngrok.ai/credits/purchases \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": 25000
}
'import requests
url = "https://api.ngrok.ai/credits/purchases"
payload = { "amount": 25000 }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({amount: 25000})
};
fetch('https://api.ngrok.ai/credits/purchases', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ngrok.ai/credits/purchases",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 25000
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.ngrok.ai/credits/purchases"
payload := strings.NewReader("{\n \"amount\": 25000\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ngrok.ai/credits/purchases")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 25000\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ngrok.ai/credits/purchases")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 25000\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"status": "pending",
"amountCents": 123,
"currency": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"failureCode": "<string>",
"failureMessage": "<string>",
"completionUrl": "<string>"
}{
"statusCode": 123,
"msg": "<string>",
"details": {},
"errorCode": "<string>"
}Start a Credit Purchase
Start an off-session charge of the account’s saved card to buy AI Gateway credits, then poll the purchase for its terminal outcome.
curl --request POST \
--url https://api.ngrok.ai/credits/purchases \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": 25000
}
'import requests
url = "https://api.ngrok.ai/credits/purchases"
payload = { "amount": 25000 }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({amount: 25000})
};
fetch('https://api.ngrok.ai/credits/purchases', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ngrok.ai/credits/purchases",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 25000
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.ngrok.ai/credits/purchases"
payload := strings.NewReader("{\n \"amount\": 25000\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ngrok.ai/credits/purchases")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 25000\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ngrok.ai/credits/purchases")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 25000\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"status": "pending",
"amountCents": 123,
"currency": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"failureCode": "<string>",
"failureMessage": "<string>",
"completionUrl": "<string>"
}{
"statusCode": 123,
"msg": "<string>",
"details": {},
"errorCode": "<string>"
}Authorizations
Headers
Optional key that makes retries safe. Reusing the same key returns the existing purchase instead of starting a second charge.
Keys are scoped to the account and this operation, can be up to 255 characters, and should be treated as permanently used. If the header is missing or empty, replay protection is disabled.
Body
Response
The purchase attempt that was started.
Current state of the purchase. Poll GET until it reaches a terminal state (succeeded or failed).
An asynchronous webhook records succeeded and actionRequired, and
a periodic sweep backstops a lost webhook. A purchase can therefore
stay pending until the next sweep runs, after the charge itself
settles.
actionRequired means the card issuer asked for 3-D Secure
approval. Open completionUrl to approve the payment.
pending, actionRequired, succeeded, failed Was this page helpful?