Create an incoming payment grant request
Last reviewed: Nov 3, 2026
The Grant Request API lets you request a grant for incoming payment, outgoing payment, and quote resources.
Before your client can call most of the Open Payments APIs, it must receive a grant from the appropriate authorization server.
The code snippets below let an authenticated client request a grant for an incoming payment. The request to the authorization server must indicate the incoming-payment and the actions the client wants to take at the resource server.
Before you begin
Section titled “Before you begin”We recommend you create an account on the Interledger test network. Creating an account allows you to test your client against the Open Payments APIs by using an ILP-enabled wallet funded with play money.
Request an incoming payment grant
Section titled “Request an incoming payment grant”Initial configuration
If you’re using JavaScript, only do the first step.
-
Add
"type": "module"topackage.json. -
Add the following to
tsconfig.json{"compilerOptions": {"target": "ES2022","module": "ES2022"}}
// Import dependenciesimport { createAuthenticatedClient, isFinalizedGrantWithAccessToken} from '@interledger/open-payments'
// Initialize clientconst client = await createAuthenticatedClient({ walletAddressUrl: CLIENT_WALLET_ADDRESS, privateKey: PRIVATE_KEY_PATH, keyId: KEY_ID})
// Get wallet address informationconst walletAddress = await client.walletAddress.get({ url: WALLET_ADDRESS})
// Request incoming payment grantconst grant = await client.grant.request( { url: walletAddress.authServer }, { access_token: { access: [ { type: 'incoming-payment', actions: ['list', 'read', 'read-all', 'complete', 'create'] } ] } })
// Check grant stateif (!isFinalizedGrantWithAccessToken(grant)) { throw new Error('Expected finalized grant')}
// Outputconsole.log('INCOMING_PAYMENT_ACCESS_TOKEN =', grant.access_token.value)console.log( 'INCOMING_PAYMENT_ACCESS_TOKEN_MANAGE_URL = ', grant.access_token.manage)// Import dependenciesuse open_payments::client::api::UnauthenticatedResources;use open_payments::client::AuthenticatedResources;use open_payments::types::auth::{ AccessItem, AccessTokenRequest, GrantRequest, GrantResponse, IncomingPaymentAction,};
// Initialize client// Authenticated client can be also used for unauthenticated resourceslet client = create_authenticated_client()?;
// Get wallet address informationlet wallet_address_url = get_env_var("WALLET_ADDRESS_URL")?;let wallet_address = client.wallet_address().get(&wallet_address_url).await?;
//Request incoming payment grantlet grant_request = GrantRequest::new( AccessTokenRequest { access: vec![AccessItem::IncomingPayment { actions: vec![ IncomingPaymentAction::Create, IncomingPaymentAction::Read, IncomingPaymentAction::ReadAll, IncomingPaymentAction::List, IncomingPaymentAction::Complete, ], identifier: None, }], }, None,);
println!( "Grant request JSON: {}", serde_json::to_string_pretty(&grant_request)?);
let response = client .grant() .request(&wallet_address.auth_server, &grant_request, None) .await?;
// Outputmatch response { GrantResponse::WithToken { access_token, .. } => { println!("Received access token: {:#?}", access_token.value); println!( "Received access token manage URL: {:#?}", access_token.manage ); } GrantResponse::WithInteraction { .. } => { unreachable!("Interaction not required for incoming payments"); }}// Import dependenciesuse OpenPayments\AuthClient;use OpenPayments\Config\Config;
// Initialize client$config = new Config( $WALLET_ADDRESS, $PRIVATE_KEY, $KEY_ID);$opClient = new AuthClient($config);
// Get wallet address information$wallet = $opClient->walletAddress()->get([ 'url' => $config->getWalletAddressUrl()]);
// Request incoming payment grant$grant = $opClient->grant()->request( [ 'url' => $wallet->authServer ], [ 'access_token' => [ 'access' => [ [ 'type' => 'incoming-payment', 'actions' => ['read', 'complete', 'create', 'list'] ] ] ] ]);
// Check grant stateif (!$grant instanceof \OpenPayments\Models\Grant) { throw new \Error('Expected non-interactive grant');}
// Outputecho 'INCOMING_PAYMENT_GRANT: ' . $grant->access_token->value . PHP_EOL;echo "INCOMING_PAYMENT_ACCESS_TOKEN_MANAGE_URL = " . $grant->access_token->manage . PHP_EOL;echo 'GRANT OBJECT: ' . PHP_EOL . print_r($grant, true);package main
// Import dependenciesimport ( "context" "encoding/json" "fmt" "log"
op "github.com/interledger/open-payments-go" as "github.com/interledger/open-payments-go/generated/authserver")
func main() { // Initialize client client, err := op.NewAuthenticatedClient(WALLET_ADDRESS_URL, PRIVATE_KEY_BASE_64, KEY_ID) if err != nil { log.Fatalf("Error creating authenticated client: %v\n", err) }
// Get wallet address information walletAddress, err := client.WalletAddress.Get(context.TODO(), op.WalletAddressGetParams{ URL: WALLET_ADDRESS_URL, }) if err != nil { log.Fatalf("Error fetching wallet address: %v\n", err) }
// Request incoming payment grant incomingAccess := as.AccessIncoming{ Type: as.IncomingPayment, Actions: []as.AccessIncomingActions{ as.AccessIncomingActionsCreate, as.AccessIncomingActionsRead, as.AccessIncomingActionsList, as.AccessIncomingActionsComplete, }, } accessItem := as.AccessItem{} if err := accessItem.FromAccessIncoming(incomingAccess); err != nil { log.Fatalf("Error creating AccessItem: %v\n", err) } accessToken := as.AccessTokenRequest{ Access: []as.AccessItem{accessItem}, }
var grantRequest as.GrantRequest if err := grantRequest.FromGrantRequestWithAccessToken(as.GrantRequestWithAccessToken{AccessToken: accessToken}); err != nil { log.Fatalf("Error building grant request: %v\n", err) } grant, err := client.Grant.Request(context.TODO(), op.GrantRequestParams{ URL: *walletAddress.AuthServer, RequestBody: grantRequest, }) if err != nil { log.Fatalf("Error requesting grant: %v\n", err) }
// Check grant state if grant.IsInteractive() { log.Fatalf("Expected non-interactive grant") }
// Output grantJSON, err := json.MarshalIndent(grant, "", " ") if err != nil { log.Fatalf("Error marshaling grant: %v\n", err) } fmt.Println("GRANT:", string(grantJSON)) fmt.Println("INCOMING_PAYMENT_ACCESS_TOKEN =", grant.AccessToken.Value) fmt.Println( "INCOMING_PAYMENT_ACCESS_TOKEN_MANAGE_URL =", grant.AccessToken.Manage, )}// Import dependenciesimport org.interledger.openpayments.httpclient.OpenPaymentsHttpClient;import org.interledger.openpayments.IOpenPaymentsClient;import org.interledger.openpayments.model.grant.AccessAction;
// Initialize clientvar client = OpenPaymentsHttpClient.defaultClient("WalletAddress","PrivateKeyPEM","KeyId");
// Get wallet address informationvar receiverWallet = client.walletAddress().get("https://cloudninebank.example.com/customer");
// Request incoming payment grant (default):var grantRequest = client.auth().grant().incomingPayment(receiverWallet);
// Request incoming payment grant (specifying actions):var grantRequestWithActions = client.auth().grant().incomingPayment(receiverWallet, AccessAction.read, AccessAction.complete, AccessAction.create);
// Outputlog.info("INCOMING_PAYMENT_GRANT: {}", grantRequest);// Import dependenciesusing Microsoft.Extensions.DependencyInjection;using Newtonsoft.Json;using OpenPayments.Sdk.Clients;using OpenPayments.Sdk.Extensions;using OpenPayments.Sdk.Generated.Auth;using OpenPayments.Sdk.HttpSignatureUtils;
// Initialize clientvar client = new ServiceCollection() .UseOpenPayments(opts => { opts.UseAuthenticatedClient = true; opts.KeyId = CLIENT_ID; opts.PrivateKey = KeyUtils.LoadPem(CLIENT_SECRET); opts.ClientUrl = new Uri(CLIENT_WALLET_ADDRESS); }) .BuildServiceProvider() .GetRequiredService<IAuthenticatedClient>();
// Get wallet address informationvar walletAddress = await client.GetWalletAddressAsync(WALLET_ADDRESS);
// Request incoming payment grantvar grant = await client.RequestGrantAsync( new RequestArgs { Url = walletAddress.AuthServer }, new GrantCreateBody { AccessToken = new AccessToken { Access = [ new IncomingAccess { Actions = [ Actions.List, Actions.Read, Actions.ReadAll, Actions.Complete, Actions.Create, ], }, ], }, });
// Check grant stateif (grant.Interact != null) throw new Exception("Expected non-interactive grant");
// OutputConsole.WriteLine(JsonConvert.SerializeObject(grant, Formatting.Indented));