Skip to main content
Once you’ve created policies in the Developer Portal, you can fetch their details programmatically. This guide shows how to retrieve policy information using the REST API and TypeScript SDKs.

Prerequisites

Before fetching policies, ensure you have:
  • An API key created in the Developer Portal
  • A policy created that you want to fetch
  • The policy ID (visible in the portal’s policy details)

Installing the SDK

npm install @swig-wallet/api
# or
bun add @swig-wallet/api

Fetching a Policy

Using the REST API

Make a GET request to the policies endpoint:
curl -X GET "https://dashboard.onswig.com/api/v1/policies/{policyId}" \
  -H "Authorization: Bearer sk_your_api_key"
Replace {policyId} with your actual policy ID (e.g., clx1234567890abcdef). Example Response:
{
  "id": "clx1234567890abcdef",
  "name": "user-wallet-policy",
  "description": "Standard user wallet with transfer limits",
  "authority": {
    "type": "Ed25519",
    "publicKey": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"
  },
  "actions": [
    { "type": "SolLimit", "amount": "1000000000" },
    { "type": "TokenLimit", "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount": "1000000" }
  ]
}

Using the SDK

import { SwigApiClient } from '@swig-wallet/api';

// Initialize the client
const client = new SwigApiClient({
  apiKey: 'sk_your_api_key',
  portalUrl: 'https://dashboard.onswig.com',
});

// Fetch a policy
async function getPolicy(policyId: string) {
  const { data: policy, error } = await client.policies.get(policyId);

  if (error) {
    console.error(`Error fetching policy: ${error.message}`);
    console.error(`Error code: ${error.code}, Status: ${error.status}`);
    return null;
  }

  console.log('Policy:', policy.name);
  console.log('Description:', policy.description);

  if (policy.authority) {
    console.log('Authority Type:', policy.authority.type);
    console.log('Authority Key:', policy.authority.publicKey);
  } else {
    console.log('Authority: Not configured (provide at wallet creation)');
  }

  console.log('Actions:', policy.actions.map(a => a.type).join(', '));

  return policy;
}

// Usage
const policy = await getPolicy('clx1234567890abcdef');

SDK Comparison

Feature@swig-wallet/api@swig-wallet/developer
Error handlingReturns { data, error }Throws SwigError
Policy typeBasic Policy interfaceRich Policy class with methods
Authority infoRaw config objectAuthorityInfo with isSession(), isEd25519(), etc.
ActionsRaw arrayActions with canSpendSol(), solSpendLimit(), etc.
Best forLow-level controlDeveloper convenience

Response Types

Policy

interface Policy {
  /** Unique policy ID */
  id: string;
  /** Policy name */
  name: string;
  /** Optional description */
  description: string | null;
  /** Authority configuration (signer) - null if not configured */
  authority: AuthorityConfig | null;
  /** Action configurations (permissions) */
  actions: ActionConfig[];
}

Authority Configuration

The authority field can be one of several types:
type AuthorityConfig =
  | { type: 'Ed25519'; publicKey: string }
  | { type: 'Ed25519Session'; publicKey: string; maxDurationSlots: string }
  | { type: 'Secp256k1'; publicKey: string }
  | { type: 'Secp256k1Session'; publicKey: string; maxDurationSlots: string }
  | { type: 'Secp256r1'; publicKey: string }
  | { type: 'Secp256r1Session'; publicKey: string; maxDurationSlots: string };

Action Configuration

The actions array contains one or more action configurations:
type ActionConfig =
  // General permissions
  | { type: 'All' }
  | { type: 'AllButManageAuthority' }
  | { type: 'ManageAuthority' }

  // SOL transfer limits
  | { type: 'SolLimit'; amount: string }
  | { type: 'SolRecurringLimit'; recurringAmount: string; window: string }
  | { type: 'SolDestinationLimit'; amount: string; destination: string }
  | { type: 'SolRecurringDestinationLimit'; recurringAmount: string; window: string; destination: string }

  // Token transfer limits
  | { type: 'TokenLimit'; mint: string; amount: string }
  | { type: 'TokenRecurringLimit'; mint: string; recurringAmount: string; window: string }
  | { type: 'TokenDestinationLimit'; mint: string; amount: string; destination: string }
  | { type: 'TokenRecurringDestinationLimit'; mint: string; recurringAmount: string; window: string; destination: string }

  // Program access
  | { type: 'Program'; programId: string }
  | { type: 'ProgramAll' }
  | { type: 'ProgramCurated' }

  // Staking
  | { type: 'StakeLimit'; amount: string }
  | { type: 'StakeRecurringLimit'; recurringAmount: string; window: string }
  | { type: 'StakeAll' }

  // Sub-accounts
  | { type: 'SubAccount' };

Error Handling

import { SwigApiClient, ApiError } from '@swig-wallet/api';

const client = new SwigApiClient({
  apiKey: 'sk_your_api_key',
});

const { data, error } = await client.policies.get('invalid-policy-id');

if (error) {
  // ApiError properties:
  // - message: Human-readable error message
  // - code: Error code string (e.g., 'NOT_FOUND', 'UNAUTHORIZED')
  // - status: HTTP status code
  // - details: Additional error context (if available)

  switch (error.code) {
    case 'NOT_FOUND':
      console.log('Policy does not exist');
      break;
    case 'UNAUTHORIZED':
      console.log('Invalid or expired API key');
      break;
    default:
      console.log(`Unexpected error: ${error.message}`);
  }
}

Common Errors

StatusCodeMeaning
401UNAUTHORIZEDInvalid or missing API key
403FORBIDDENAPI key doesn’t have access to this policy
404NOT_FOUND / POLICY_NOT_FOUNDPolicy ID doesn’t exist
500INTERNAL_ERRORServer error, try again later

Retry Configuration

Both SDKs support automatic retries for transient failures:
const client = new SwigApiClient({
  apiKey: 'sk_your_api_key',
  portalUrl: 'https://dashboard.onswig.com',
  retry: {
    maxRetries: 3,        // Number of retry attempts
    retryDelay: 1000,     // Initial delay in milliseconds
    backoffMultiplier: 2, // Exponential backoff multiplier
  },
});
With these settings, retries occur at: 1s, 2s, 4s (exponential backoff).
Both SDKs only retry on 5xx server errors and network failures. Client errors (4xx) are not retried.

Complete Example

import { SwigApiClient } from '@swig-wallet/api';

async function main() {
  const client = new SwigApiClient({
    apiKey: process.env.SWIG_API_KEY!,
    portalUrl: 'https://dashboard.onswig.com',
    retry: { maxRetries: 3, retryDelay: 1000 },
  });

  const policyId = 'your-policy-id';
  const { data: policy, error } = await client.policies.get(policyId);

  if (error) {
    console.error('Failed to fetch policy:', error.message);
    process.exit(1);
  }

  console.log('=== Policy Details ===');
  console.log(`ID: ${policy.id}`);
  console.log(`Name: ${policy.name}`);
  console.log(`Description: ${policy.description ?? 'None'}`);

  console.log('\n=== Authority ===');
  if (policy.authority) {
    console.log(`Type: ${policy.authority.type}`);
    console.log(`Public Key: ${policy.authority.publicKey}`);
  } else {
    console.log('No authority configured');
  }

  console.log('\n=== Actions ===');
  for (const action of policy.actions) {
    console.log(`- ${action.type}`);
  }
}

main();

Next Steps

Now that you can fetch policies, learn how to create Swig wallets using those policies.