This guide provides a detailed walkthrough of integrating with the Glider API, covering every aspect of portfolio creation, management, and automation.
Glider is a platform for creating and automating on-chain portfolios. Define your asset allocations, deposit tokens, and let Glider automate rebalancing based on your specifications.
Glider is currently in early access.
We’re currently operating on
Base with plans to expand to more chains.
Terminology
- Portfolio: A set of assets managed by the Glider platform according to your specifications.
- Portfolio Template: A blueprint that defines the composition and behavior of a portfolio, including asset allocations and rebalancing parameters.
- Vault: A secure smart contract that holds your assets on-chain and allows for automated management.
- Rebalance: The process of adjusting your portfolio’s asset allocation to match your target allocation.
- Session Key: A secure signature-based authentication method that allows Glider to execute transactions on behalf of your portfolio.
- Automation: Scheduled rebalancing of your portfolio based on your chosen time intervals or threshold triggers.
Authentication
Glider is currently in early access. Sign up for the waitlist on the Glider
App.
Prerequisites
Before you begin, you’ll need:
- A Glider platform account
- An API key for authentication
- A wallet for signing portfolio creation and transaction permissions
Authenticate
First, you need to get an API key that will authenticate your requests to the Glider API.
- Log in to the Glider platform
- Navigate to your profile settings
- Select “API Keys” and create a new key
- Store your API key securely - you’ll need to include it in the header of all API requests
# Example of including your API key in requests
curl -H "X-API-KEY: your_api_key_here" https://api.glider.fi/v1/...
API Response Format
All Glider API responses follow a consistent format:
{
"success": true, // or false for errors
"data": {
// Response data varies by endpoint
},
"correlationId": "corr_abcd1234", // For request tracking
"requestId": "req_efgh5678", // For request tracking
"timestamp": "2023-05-21T12:34:56.789Z" // ISO timestamp
}
Error responses include additional error information:
{
"success": false,
"error": {
"code": "ERROR_CODE", // Specific error code
"message": "Human-readable error message",
"details": { // Optional additional details
// Error-specific information
}
},
"correlationId": "corr_abcd1234",
"requestId": "req_efgh5678",
"timestamp": "2023-05-21T12:34:56.789Z"
}
Portfolio Management Lifecycle
Let’s walk through the complete lifecycle of portfolio management using the Glider API.
1. Portfolio Creation Process
Portfolio creation follows a signature-based authentication flow to ensure secure user authorization:
1.1 Request a signature message
First, request a message that your user will sign to authorize portfolio creation:
const signatureResponse = await fetch('https://api.glider.fi/v1/portfolio/create/signature', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
userAddress: '0xUserWalletAddress', // The user's wallet address
chainIds: [8453], // Chain IDs where the portfolio will exist (Base = 8453)
accountIndex: 0, // Optional: Used for multiple portfolios per user
}),
});
const signatureData = await signatureResponse.json();
// The signatureData.data.signatureAction.message contains the text to be signed
console.log("Message to sign:", signatureData.data.signatureAction.message);
The response will contain a signature request object that includes a message the user needs to sign:
{
"success": true,
"data": {
"userAddress": "0xUserWalletAddress",
"chainIds": [8453],
"accountIndex": 0,
"kernelVersion": "0.3.2",
"signatureAction": {
"reason": "portfolio-permission",
"type": "personal_sign",
"message": "I authorize Glider to manage my portfolio\n\n0x8ad4d95c3c3d0a1e87bfdb1d2401905db4a97d8e05e77d69e5d79397da128b81"
}
}
}
1.2 Sign the message with the user’s wallet
Next, have the user sign this message with their wallet. How you implement this will depend on the wallet provider you’re using:
// Example using ethers.js
const signature = await signer.signMessage(signatureData.data.signatureAction.message);
// Example using viem
const signature = await walletClient.signMessage({
account,
message: signatureData.data.signatureAction.message,
});
1.3 Create the portfolio with the signed message
Once you have the signature, submit it along with the original request data to create the portfolio:
const createResponse = await fetch('https://api.glider.fi/v1/portfolio/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
userAddress: signatureData.data.userAddress,
chainIds: signatureData.data.chainIds,
accountIndex: signatureData.data.accountIndex,
kernelVersion: signatureData.data.kernelVersion,
signatureAction: signatureData.data.signatureAction,
signature: signature,
// Optionally include template data to initialize the portfolio
templateData: {
name: "70/30 ETH-USDC Portfolio",
description: "A simple portfolio with 70% ETH and 30% USDC allocation",
entry: {
blockType: "weight",
weightType: "specified-percentage",
weightings: ["70", "30"],
children: [
{
blockType: "asset",
assetId: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE:8453" // ETH on Base
},
{
blockType: "asset",
assetId: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913:8453" // USDC on Base
}
]
},
tradingSettings: {
type: "threshold",
triggerPercentage: 5 // Rebalance when assets drift 5% from target
}
}
}),
});
const portfolio = await createResponse.json();
const portfolioId = portfolio.data.portfolioId;
The response will include the newly created portfolio ID and other details:
{
"success": true,
"data": {
"portfolioId": "port_abc123",
"message": "Portfolio created successfully",
"vaults": [
{
"chainId": "8453",
"address": "0xPortfolioVaultAddress"
}
]
}
}
2. Portfolio Configuration
If you didn’t include template data during portfolio creation, or if you need to update an existing portfolio’s configuration, you can use the update endpoint:
const updateResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/update`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
templateData: {
name: "Updated ETH-USDC Portfolio",
description: "A portfolio with ETH and USDC",
entry: {
blockType: "weight",
weightType: "specified-percentage",
weightings: ["60", "40"], // Changed allocation to 60/40
children: [
{
blockType: "asset",
assetId: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE:8453" // ETH on Base
},
{
blockType: "asset",
assetId: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913:8453" // USDC on Base
}
]
},
tradingSettings: {
type: "threshold",
triggerPercentage: 3 // Lower threshold to 3%
}
}
}),
});
const updatedPortfolio = await updateResponse.json();
2.1 Template Structure
The template data defines how your portfolio is structured:
name
: The display name of the portfolio (optional)
description
: A description of the portfolio (optional)
entry
: The portfolio structure (required)
blockType
: Type of portfolio structure (required, must be “weight” for weighted allocation)
weightType
: For weighted portfolios, specifies how weights are calculated (required, must be “specified-percentage”)
weightings
: Array of string percentages for each asset (required, must match the number of children)
children
: Array of assets or nested structures (required, at least 1 child)
- For assets:
{ blockType: "asset", assetId: "0xTokenAddress:chainId" }
- The assetId must follow the format
0xTokenAddress:chainId
tradingSettings
: Rebalancing configuration (optional)
type
: Type of rebalancing - “threshold” or “calendar” (required if tradingSettings is provided)
triggerPercentage
: Deviation percentage to trigger rebalancing (required if type is “threshold”)
frequency
: Rebalance frequency (required if type is “calendar”): “daily”, “weekly”, “biweekly”, “monthly”
The sum of all percentages in weightings
must equal 100, and the number of weightings must match the number of children in the template.
3. Portfolio Funding
3.1 Depositing Assets
To deposit assets into a portfolio, you first need to get the deposit instructions:
const depositResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/deposit`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
token: {
chainId: 8453,
address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // ETH on Base
amount: '0.5' // 0.5 ETH
}
}),
});
const depositData = await depositResponse.json();
The response will include transaction data that you can use to create a transaction for the user to sign:
{
"success": true,
"data": {
"to": "0xPortfolioVaultAddress",
"value": "500000000000000000", // 0.5 ETH in wei
"data": "0x...", // Transaction calldata
"chainId": 8453
}
}
You’ll need to create a transaction with this data and have the user sign and send it:
// Example using ethers.js
const tx = await signer.sendTransaction({
to: depositData.data.to,
value: depositData.data.value,
data: depositData.data.data,
chainId: depositData.data.chainId
});
// Wait for confirmation
const receipt = await tx.wait();
console.log("Deposit confirmed:", receipt.transactionHash);
3.2 Withdrawing Assets
Withdrawing assets follows a similar pattern:
const withdrawResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/withdraw`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
assets: [
{
chainId: 8453,
address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // ETH on Base
amount: '0.1' // 0.1 ETH
}
]
}),
});
const withdrawData = await withdrawResponse.json();
// Create, sign and send the transaction using the data from the response
// Similar to the deposit example above
4. Portfolio Automation
4.1 Starting Automation
Once your portfolio is funded, you can start automated rebalancing:
const startResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/start`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
runRebalanceImmediately: true, // Run a rebalance right away
interval: {
every: 86400000, // 24 hours in milliseconds
}
}),
});
const startData = await startResponse.json();
This sets up a schedule that will automatically rebalance the portfolio based on the trading settings defined in the template.
4.2 Checking Automation Status
To check the current status of portfolio automation:
const statusResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/automation/status`, {
method: 'GET',
headers: {
'X-API-KEY': API_KEY,
},
});
const statusData = await statusResponse.json();
console.log("Automation status:", statusData.data.status);
4.3 Pausing and Resuming Automation
You can pause automation when needed:
const pauseResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/pause`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
reason: "User requested pause" // Optional reason
}),
});
const pauseData = await pauseResponse.json();
And resume it later:
const resumeResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/resume`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
reason: "User requested resume" // Optional reason
}),
});
const resumeData = await resumeResponse.json();
4.4 Manually Triggering a Rebalance
You can also manually trigger a rebalance at any time:
const triggerResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/trigger`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
skipScheduleValidation: true // Allow triggering even if no schedule exists
}),
});
const triggerData = await triggerResponse.json();
5. Portfolio Monitoring
5.1 Getting Portfolio Details
To retrieve the current state of a portfolio:
const portfolioResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}`, {
method: 'GET',
headers: {
'X-API-KEY': API_KEY,
},
});
const portfolioData = await portfolioResponse.json();
This returns comprehensive data about the portfolio, including:
- Portfolio metadata (name, description, etc.)
- Assets and their balances
- Template configuration
- Vault addresses
To check the portfolio’s performance over time:
const performanceResponse = await fetch(`https://api.glider.fi/v1/portfolios/${portfolioId}/performance?timeWindow=30d`, {
method: 'GET',
headers: {
'X-API-KEY': API_KEY,
},
});
const performanceData = await performanceResponse.json();
Available time windows include: 1d
, 7d
, 30d
, 90d
, 180d
, 1y
, all
.
5.3 Viewing Transactions
To view transaction history:
const txResponse = await fetch(`https://api.glider.fi/v1/portfolios/${portfolioId}/transactions?limit=10&offset=0`, {
method: 'GET',
headers: {
'X-API-KEY': API_KEY,
},
});
const txData = await txResponse.json();
6. Advanced Portfolio Management
6.1 Executing Custom Transactions
For advanced use cases, you can execute custom transactions through the portfolio:
const executeResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/execute`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
chainId: 8453,
params: {
to: "0xTargetContractAddress",
value: "0", // ETH value in wei
data: "0x...", // Transaction calldata
}
}),
});
const executeData = await executeResponse.json();
6.2 Archiving a Portfolio
To archive a portfolio that’s no longer needed:
const archiveResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/archive`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
reason: "No longer needed" // Optional reason
}),
});
const archiveData = await archiveResponse.json();
Archived portfolios can be unarchived if needed:
const unarchiveResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/unarchive`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
resumeSchedules: true // Whether to resume automation schedules
}),
});
const unarchiveData = await unarchiveResponse.json();
6.3 Refreshing Session Keys
If a portfolio’s session keys need to be refreshed:
// Step 1: Get a new signature request
const resignResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/resign`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({}),
});
const resignData = await resignResponse.json();
// Step 2: Have the user sign the new message
const newSignature = await wallet.signMessage(resignData.data.signatureAction.message);
// Step 3: Submit the new signature
const resubmitResponse = await fetch(`https://api.glider.fi/v1/portfolio/${portfolioId}/resubmit-signature`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
signature: newSignature,
signatureAction: resignData.data.signatureAction
}),
});
const resubmitResult = await resubmitResponse.json();
7. Listing and Filtering Portfolios
To retrieve a list of all portfolios for a specific user:
const listResponse = await fetch(`https://api.glider.fi/v1/portfolios?userAddress=0xUserWalletAddress&limit=10&offset=0`, {
method: 'GET',
headers: {
'X-API-KEY': API_KEY,
},
});
const portfolioList = await listResponse.json();
Available query parameters include:
userAddress
: Filter by owner address
portfolioId
: Filter by portfolio ID
portfolioAddress
: Filter by portfolio vault address
portfolioChainId
: Filter by chain ID
isArchived
: Filter for archived or active portfolios
hasAutomation
: Filter for portfolios with automation enabled
limit
, offset
: For pagination
sort
, order
: For sorting results
search
: Text search
chainId
: Filter by chain ID
tag
: Filter by portfolio tag
includeAssets
: Include detailed asset data
realtime
: Use real-time blockchain data instead of cached data
Error Handling
The API uses standard HTTP response codes:
2xx
: Success
4xx
: Client error (invalid request, authentication error, etc.)
5xx
: Server error
All error responses follow this format:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
// Additional error details if available
}
},
"correlationId": "corr_abc123",
"requestId": "req_xyz789",
"timestamp": "2023-05-21T12:34:56.789Z"
}
Common error codes include:
INVALID_API_KEY
: The API key is missing or invalid
INVALID_REQUEST
: The request is malformed
PORTFOLIO_NOT_FOUND
: The specified portfolio doesn’t exist
PORTFOLIO_TEMPLATE_VALIDATION_ERROR
: The template data is invalid
UNAUTHORIZED
: The user doesn’t have permission to perform this action
Best Practices
Rate Limiting
The API has rate limits to ensure fair usage. If you exceed these limits, you’ll receive a 429 Too Many Requests
response. Consider implementing:
- Exponential backoff for retries
- Caching frequently accessed data
- Batching requests where possible
Security
- Never expose your API key in client-side code
- Always validate user input before sending it to the API
- Use HTTPS for all API requests
- Implement proper error handling to avoid exposing sensitive information
- Fetch only the data you need
- Use pagination for large data sets
- Consider using the
includeAssets=false
parameter when listing portfolios if you don’t need asset details
- Use the
realtime=false
parameter (default) for faster response times
Next Steps
Now that you understand the complete Glider API integration process, you can: