API Reference

The Good Plan API allows you to programmatically create payment plans from your invoicing system, CRM, or other business tools.

Authentication

All API requests require authentication using an API key passed as a Bearer token.

Getting Your API Key

  1. Log into Good Plan
  2. Navigate to Dashboard → Webhooks
  3. Click "Generate API Key"
  4. Copy the key immediately (it's only shown once)

Your API key will look like: gp_a1b2c3d4e5f6... (64 characters)

Using Your API Key

Include the API key in the Authorization header:

Authorization: Bearer gp_your_api_key_here

Endpoints

Create Plan

Endpoint: POST /api/v1/plans

Creates a new payment plan with customizable options. Customer receives an email with a portal link to choose their preferred payment schedule.

Request Body

Field Type Required Description
customer.name string Customer's full name
customer.email string Customer's email address
customer.phone string Customer's phone number
invoice.amount number Amount owed (minimum 1.00)
invoice.invoice_number string Your invoice/reference number
invoice.description string Description of what's owed
options.intervals array Payment frequencies: weekly, biweekly, monthly
options.durations array Number of payments: 2-96
send_introduction_email boolean Send intro email to customer (default: true)

About send_introduction_email:

  • When true (default), the customer receives an email with their portal link
  • When false, no email is sent - use this if you want to send the portal link yourself
  • The customer_portal_url is always returned in the response regardless of this setting

Minimal Request Example

{
  "customer": {
    "name": "John Doe",
    "email": "john@example.com"
  },
  "invoice": {
    "amount": 1200.00
  }
}

Full Request Example

{
  "customer": {
    "name": "John Doe",
    "email": "john@example.com",
    "phone": "+1-555-123-4567"
  },
  "invoice": {
    "amount": 1200.00,
    "invoice_number": "INV-2024-001",
    "description": "Past due consulting services"
  },
  "options": {
    "intervals": ["weekly", "monthly"],
    "durations": [3, 6, 12]
  },
  "send_introduction_email": true
}

Success Response (201 Created)

{
  "plan_id": 42,
  "customer_portal_url": "https://goodplan.com/plan/abc123...",
  "plan_options": [
    {
      "id": 101,
      "installments": 3,
      "interval": "monthly",
      "payment_amount": "400.00",
      "first_payment_date": "2025-12-04",
      "final_payment_date": "2026-02-04"
    }
  ],
  "customer": {
    "id": 567,
    "name": "John Doe",
    "email": "john@example.com"
  },
  "invoice": {
    "id": 890,
    "amount": "1200.00",
    "invoice_number": "INV-2024-001"
  }
}

Error Responses

401 Unauthorized - Missing or invalid API key:

{
  "error": "API key required",
  "message": "Please provide an API key in the Authorization header"
}

422 Validation Error - Invalid request data:

{
  "error": "Validation failed",
  "errors": {
    "customer.email": ["The customer.email must be a valid email address."],
    "invoice.amount": ["The invoice.amount must be at least 1."]
  }
}

403 Forbidden - Plan limit reached:

{
  "error": "Plan limit reached",
  "message": "Your subscription plan limit has been reached."
}

Health Check

Endpoint: GET /api/health

Verify API availability (no authentication required).

Response (200 OK):

{
  "status": "ok",
  "version": "1.0.0",
  "timestamp": "2025-11-27T01:15:30Z"
}

Code Examples

cURL

curl -X POST https://goodplan.com/api/v1/plans \
  -H "Authorization: Bearer gp_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "name": "John Doe",
      "email": "john@example.com"
    },
    "invoice": {
      "amount": 1200.00,
      "invoice_number": "INV-2024-001"
    }
  }'

PHP

$apiKey = 'gp_your_api_key_here';

$data = [
    'customer' => [
        'name' => 'John Doe',
        'email' => 'john@example.com',
    ],
    'invoice' => [
        'amount' => 1200.00,
        'invoice_number' => 'INV-2024-001',
    ],
];

$ch = curl_init('https://goodplan.com/api/v1/plans');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($data),
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 201) {
    $result = json_decode($response, true);
    echo "Portal URL: " . $result['customer_portal_url'];
}

Python

import requests

api_key = 'gp_your_api_key_here'
url = 'https://goodplan.com/api/v1/plans'

headers = {
    'Authorization': f'Bearer {api_key}',
    'Content-Type': 'application/json'
}

data = {
    'customer': {
        'name': 'John Doe',
        'email': 'john@example.com'
    },
    'invoice': {
        'amount': 1200.00,
        'invoice_number': 'INV-2024-001'
    }
}

response = requests.post(url, headers=headers, json=data)

if response.status_code == 201:
    result = response.json()
    print(f"Portal URL: {result['customer_portal_url']}")

Integration Patterns

Automatic Plan Creation

Create plans automatically when invoices become overdue:

  1. Check for overdue invoices in your system
  2. For each overdue invoice, call the API to create a plan
  3. Send the customer_portal_url to your customer
  4. Customer selects their preferred payment schedule
  5. Receive webhooks when payments are made

Zapier Integration

  1. In Zapier, choose "Webhooks by Zapier" as the action
  2. Select "POST"
  3. URL: https://yourdomain.com/api/v1/plans
  4. Add headers:
    • Authorization: Bearer {{your_api_key}}
    • Content-Type: application/json
  5. Map your trigger fields to the request body

Rate Limiting

  • Default: 60 requests per minute per API key
  • Burst: 10 requests per second

Rate limit info is included in response headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59

Best Practices

  1. Store API keys securely - Use environment variables, never commit to version control
  2. Handle errors gracefully - Check status codes and error messages
  3. Use timeouts - Set reasonable timeouts (30 seconds recommended)
  4. Validate data - Validate customer email and invoice amount before sending
  5. Test in development - Use the health check endpoint to verify connectivity

Next Steps

  • Set up Webhooks to receive updates
  • Configure Zapier integration
  • Build custom integration in your invoicing system

Related Articles

Need more help?

Can't find what you're looking for?

Contact Support →