Getting Started with the Extend API | Virtual Card & Expense Management Integration Guide
Getting Started with the Extend API: A Complete Guide
Author
Ashkan Abedian
Guest Author
TL;DR
- The Extend API lets businesses integrate virtual card issuing, approvals, transaction monitoring, and expense management directly into their systems—using the credit cards they already have.
- Setup is simple: generate API keys from your Extend account, authenticate securely, and start building your integration in Python.
- The sample project walks through creating an API client, managing credit cards, issuing and closing virtual cards, and retrieving spending data.
- With this setup, you can automate card creation, enforce spend controls programmatically, and streamline reconciliation workflows.
- Extend’s API is designed to reduce manual AP/AR work, strengthen security, and embed spend management features seamlessly into your business apps.
In today's digital-first business environment, managing corporate expenses efficiently is crucial.
Extend gives businesses access to powerful virtual card issuing and expense management features with their credit card of choice. In this guide, we'll walk through setting up your API access and creating a simple service that demonstrates how to interact with the Extend API.
What is Extend?
Extend allows businesses to connect their credit cards and get instant access to a suite of card controls and bookkeeping features. By integrating with the Extend API, you can embed virtual card issuing, approvals, transaction monitoring, and expense processing capabilities into your own proprietary workflows. This provides a secure and flexible solution for managing business expenses while significantly reducing manual work surrounding AP/AR and bookkeeping processes.
Prerequisites
Before we begin, make sure you have:
- An Extend account (Sign up at https://app.paywithextend.com/)
- Organization owner privileges
- An enrolled credit card account
Setting up your API access
Step 1: Request API access
- Navigate to your organization's settings page
- Click on the "API Keys" tab
- Click on the "Setup API Keys" button
A member of the Extend team will review your request and approve it. Once approved, you'll be able to generate an API key.
Step 2: Generate your API key
- After approval, return to the API Keys tab
- Click the "Generate API Key" button
- Copy both the API key and secret - you'll need these for authentication
Store these credentials securely. They won't be displayed again, and you'll need to generate a new key when this one expires (after 365 days).
Building your first integration
Let's create a Python service that demonstrates how to interact with the Extend API. We'll build this step by step, explaining each component as we go.
Project setup
First, let's set up our development environment:
mkdir extend-api-demo
cd extend-api-demo
python -m venv venv
source venv/bin/activate # On Windows, use: venv\Scripts\activate
pip install requests python-dotenv
Setting up authentication
Before we start coding, we need to set up our authentication. Extend uses a combination of an API key and an authentication token for secure API access.
First, create a .env file to store your credentials:
EXTEND_API_KEY=your_api_key_here
EXTEND_API_SECRET=your_api_secret_here
EXTEND_EMAIL=your_extend_email_here
Next, create a script called generate_token.sh to generate your authentication token:
#!/bin/bash
# Check if both arguments are provided
if [ $# -ne 2 ]; then
echo "Usage: $0 "
exit 1
fi
# Assign the arguments to variables
API_KEY=$1
SECRET=$2
# Combine the API key and secret with a colon separator
CREDENTIALS="${API_KEY}:${SECRET}"
# Base64 encode the credentials
SECURITY_TOKEN=$(echo -n "${CREDENTIALS}" | base64)
echo "Your security token is: ${SECURITY_TOKEN}"
echo "Add this to your .env file as EXTEND_AUTHENTICATION_TOKEN=${SECURITY_TOKEN}"
Make the script executable and run it:
chmod +x generate_token.sh
./generate_token.sh your_api_key your_api_secret
Update your .env file with the generated token:
EXTEND_API_KEY=your_api_key_here
EXTEND_AUTHENTICATION_TOKEN=your_generated_token_here
EXTEND_EMAIL=your_extend_email_here
Creating the base client
Let's start by creating our extend_client.py file with the basic client structure and authentication:
import os
import requests
from dotenv import load_dotenv
class ExtendClient:
def __init__(self):
load_dotenv()
self.authentication_token = os.getenv('EXTEND_AUTHENTICATION_TOKEN')
self.api_key = os.getenv('EXTEND_API_KEY')
self.base_url = 'https://apiv2.paywithextend.com'
self.proxy_url = 'https://v-apiv2.paywithextend.com'
self.extend_email = os.getenv('EXTEND_EMAIL')
if not self.authentication_token or not self.api_key:
raise ValueError("Authentication token and API key must be set in .env file")
def _get_auth_headers(self):
"""Generate authentication headers for API requests"""
return {
"Authorization": f"Basic {self.authentication_token}",
"x-extend-api-key": self.api_key,
"Accept": "application/vnd.paywithextend.v2021-03-12+json"
}
This base client:
- Loads environment variables from .env
- Validates that required credentials are present
- Provides a method to generate authentication headers for API requests
Adding credit card management
Now let's add methods to manage credit cards. Add these methods to your ExtendClient class:
def get_credit_cards(self):
"""Retrieve all enrolled credit cards"""
response = requests.get(
f"{self.base_url}/creditcards",
headers=self._get_auth_headers()
)
response.raise_for_status()
return response.json()
This method:
- Makes a GET request to the credit cards endpoint
- Uses our authentication headers
- Returns the JSON response with all enrolled credit cards
Implementing virtual card operations
Let's add the virtual card management functionality. Add these methods to your ExtendClient class:
def create_virtual_card(self, credit_card_id, balance_cents, valid_to_date, display_name):
"""Create a new virtual card"""
payload = {
"recipient": self.extend_email,
"displayName": display_name,
"balanceCents": balance_cents,
"validTo": valid_to_date,
"creditCardId": credit_card_id
}
response = requests.post(
f"{self.base_url}/virtualcards",
headers=self._get_auth_headers(),
json=payload
)
response.raise_for_status()
return response.json()
def get_virtual_card_spend_info(self, virtual_card_id):
"""Retrieve spending information for a virtual card"""
response = requests.get(
f"{self.proxy_url}/virtualcards/{virtual_card_id}",
headers=self._get_auth_headers()
)
response.raise_for_status()
data = response.json()
virtual_card = data.get("virtualCard", {})
return {
"id": virtual_card.get("id"),
"vcn": virtual_card.get("vcn"),
"securityCode": virtual_card.get("securityCode"),
"address": virtual_card.get("address"),
"expires": virtual_card.get("expires")
}
def close_virtual_card(self, virtual_card_id):
"""Close a virtual card"""
response = requests.put(
f"{self.base_url}/virtualcards/{virtual_card_id}/close",
headers=self._get_auth_headers()
)
response.raise_for_status()
return response.json()
These methods provide:
- Virtual card creation with customizable parameters. There are more optional parameters that you can set; refer to the API documentation for more information
- Secure retrieval of card spending information. Note that the proxy URL is used to retrieve the card spending information. You can read more about this here
- Card closure functionality
Using the client
Now that we have our client implementation, let's create a main.py file to demonstrate how to use it:
from extend_client import ExtendClient
from datetime import datetime, timedelta
def main():
# Initialize the client
client = ExtendClient()
try:
# Get available credit cards
print("Fetching credit cards...")
credit_cards = client.get_credit_cards()
if not credit_cards.get('creditCards'):
print("No credit cards found. Please enroll a card first.")
return
card_id = credit_cards['creditCards'][0]["id"]
print(f"Found credit card with ID: {card_id}")
# Create a virtual card
valid_to_date = (datetime.now() + timedelta(days=365)).strftime("%Y-%m-%d")
print("\nCreating virtual card...")
virtual_card = client.create_virtual_card(
credit_card_id=card_id,
balance_cents=1000, # $10.00
valid_to_date=valid_to_date,
display_name="Marketing Expenses"
)
virtual_card_id = virtual_card['virtualCard']['id']
print(f"Created virtual card with ID: {virtual_card_id}")
# Get card details
print("\nRetrieving card details...")
card_info = client.get_virtual_card_spend_info(virtual_card_id)
print("Card Details:")
print(f"Card Number: {card_info['vcn']}")
print(f"Security Code: {card_info['securityCode']}")
print(f"Expires: {card_info['expires']}")
print(f"Billing Address: {card_info['address']}")
# Close the card
print("\nClosing virtual card...")
client.close_virtual_card(virtual_card_id)
print("Card closed successfully")
except Exception as e:
print(f"An error occurred: {str(e)}")
if __name__ == "__main__":
main()
This example demonstrates:
- Client initialization
- Error handling
Running the example
- Make sure your .env file is properly configured with your API credentials.
- Run the example:
python main.py
This will:
- Fetch your enrolled credit cards
- Create a new virtual card
- Retrieve the card details
- Close the card
Next steps
This example demonstrates the basic functionality of the Extend API. You can now:
- Automate virtual card creation for various business needs
- Implement programmatic controls for card management
- Build custom integrations with your existing business systems
Need more information about our API capabilities? Get our API documentation
Need help?
If you need assistance with your integration, you can contact our support team.
Happy coding!
About the author
Ashkan Abedian
Guest Author
Ashkan is a Product Manager & Engineer, driving intelligent automation and personalized platform experiences. With a background in backend engineering, Ashkan previously worked on Extend’s Core Services team, contributing to critical integrations and embedded payments infrastructure. He holds a degree in Management Engineering from the University of Waterloo.