Welcome to the Grid Flow Public API documentation. Our API enables you to programmatically manage grid connection applications, upload and manage documents, and integrate fully with the Grid Flow system without needing the web interface.
Base URL: https://app.renewablehelp.co.uk/api/v1
Contents
1. Authentication & API Keys
All API endpoints require authentication via API key. Include your API key in the request header:
Obtaining an API Key
- Log in to your Grid Flow account at app.renewablehelp.co.uk
- Navigate to Account Settings → API Keys
- Click Create New API Key
- Select the scopes (permissions) you need
- Copy and securely store your key (it won’t be shown again)
gf_live_.2. API Scopes
When creating an API key, you select which scopes (permissions) it has. Only request the scopes you need.
| Scope | Description |
|---|---|
applications:read |
View applications and their details |
applications:write |
Create new applications and update existing ones |
applications:delete |
Delete draft applications |
applications:submit |
Submit applications for processing (generates documents) |
status:write |
Change application status within allowed transitions |
documents:read |
List and download documents attached to applications |
documents:write |
Upload new documents and delete existing ones |
documents:generate |
Trigger document generation for paper applications |
document_requests:read |
View document request status and details |
document_requests:write |
Create and manage document requests |
devices:read |
Search ENA approved device databases |
installers:read |
View saved installer/contractor information |
installers:write |
Create and update installers |
bulk:import |
Import multiple applications via bulk endpoint |
3. Rate Limiting
API requests are rate limited to 1000 requests per hour per API key. Rate limit info is included in response headers:
X-RateLimit-Remaining: 945
X-RateLimit-Reset: 2024-01-15T11:00:00Z
4. Applications API
Manage grid connection applications programmatically.
List Applications
/api/v1/applications
applications:read
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| status | string | Optional Filter by status (draft, submitted, approved, etc.) |
| type | string | Optional Filter by application_type |
| dno | string | Optional Filter by DNO code |
| mpan | string | Optional Filter by MPAN (partial match) |
| reference | string | Optional Filter by reference number (partial match) |
| installer_id | string | Optional Filter by saved installer ID |
| search | string | Optional Full text search across name, email, address, reference, MPAN |
| created_after | ISO 8601 | Optional Filter by created date |
| created_before | ISO 8601 | Optional Filter by created date |
| limit | integer | Optional Results per page (default: 50, max: 100) |
| offset | integer | Optional Pagination offset |
Response
“applications”: [
{
“id”: “550e8400-e29b-41d4-a716-446655440000”,
“reference_number”: “FLOW-1704067200-ABC12”,
“application_type”: “solar_pv”,
“submission_method”: “paper”,
“applicant_name”: “John Smith”,
“applicant_email”: “john@example.com”,
“applicant_phone”: “07700900123”,
“applicant_company_name”: “Smith Solar Ltd”,
“site_address”: “123 Solar Street, London, SW1A 1AA”,
“postcode”: “SW1A 1AA”,
“mpan”: “1234567890123”,
“dno_name”: “UK Power Networks”,
“dno_code”: “UKPN”,
“installer_id”: “uuid-of-installer”,
“status”: “submitted”,
“payment_status”: “paid”,
“created_at”: “2024-01-15T10:30:00Z”,
“updated_at”: “2024-01-15T12:00:00Z”
}
],
“pagination”: {
“total”: 156,
“limit”: 50,
“offset”: 0,
“hasMore”: true
}
}
Get Application
/api/v1/applications/{id}
applications:read
Returns full application details including equipment_details and generated_documents JSON fields.
Create Application
/api/v1/applications
applications:write
Request Body
“applicationType”: “solar_pv”, // Required: solar_pv, solar_pv_and_battery, battery_storage_only, ev_charger, heat_pump, v2g_ev_charger
“submissionMethod”: “paper”, // Optional: paper (default) or ena_connect
“mpan”: “1234567890123”, // Required for document generation – determines DNO
“applicant”: { // Required
“firstName”: “John”, // Required
“lastName”: “Smith”, // Required
“email”: “john@example.com”, // Required
“phone”: “07700900123”,
“companyName”: “Smith Solar Ltd”,
“address”: “456 Business Park”,
“addressLine2”: “Suite 100”,
“city”: “Manchester”,
“postcode”: “M1 1AA”
},
“site”: { // Required
“street”: “123 Solar Street”, // Required
“addressLine2”: “”,
“city”: “London”, // Required for EV/HP applications
“postcode”: “SW1A 1AA”, // Required
“companyName”: “”, // If site is a business
“contactName”: “Jane Doe”, // Site contact (if different from applicant)
“contactEmail”: “jane@example.com”,
“contactPhone”: “07700900456”
},
“dno”: { // Optional – auto-detected from MPAN
“name”: “UK Power Networks”,
“code”: “UKPN”,
“email”: “connections@ukpn.co.uk”,
“reference”: “”
},
“installerId”: “uuid”, // Optional – reference to saved installer
“equipment”: {
“phase”: 1, // 1 for single phase, 3 for three phase
“fuseSize”: 80, // Main fuse size in amps
“inverters”: [
{
“manufacturer”: “SolarEdge”,
“model”: “SE5000H”,
“capacity”: 5.0, // kW
“enaCode”: “ENS123456”, // ENA registration number
“phase”: 1,
“existing”: false, // Is this an existing installation?
“remove”: false, // Is this being removed?
“panelWattage”: 400,
“panelCount”: 12,
“panelModel”: “JA Solar 400W”,
“battery”: {
“manufacturer”: “Tesla”,
“model”: “Powerwall 2”,
“capacity”: 13.5 // kWh
}
}
],
“evChargers”: [ // For ev_charger/v2g applications
{
“manufacturer”: “Ohme”,
“model”: “Home Pro”,
“capacity”: 7.4,
“enaCode”: “EVC123456”,
“type”: “AC” // AC, DC, or V2G
}
],
“heatPumps”: [ // For heat_pump applications
{
“manufacturer”: “Mitsubishi”,
“model”: “Ecodan PUZ”,
“capacity”: 8.5,
“enaCode”: “HP123456”
}
]
},
“installer”: { // Optional – inline installer details (alternative to installerId)
“companyName”: “Smith Solar Ltd”,
“contactName”: “John Smith”,
“email”: “john@smithsolar.com”,
“phone”: “07700900123”,
“address”: “456 Business Park”,
“city”: “Manchester”,
“postcode”: “M1 1AA”
}
}
Response
“message”: “Application created”,
“application”: {
“id”: “550e8400-e29b-41d4-a716-446655440000”,
“referenceNumber”: “FLOW-1704067200-ABC12”,
“applicationType”: “solar_pv”,
“submissionMethod”: “paper”,
“status”: “draft”
}
}
Update Application
/api/v1/applications/{id}
applications:write
Updates an application. Can update non-draft applications (except protected fields like reference_number and ena_application_id).
“mpan”: “1234567890124”,
“applicant”: {
“firstName”: “Jane”,
“lastName”: “Smith”
},
“site”: {
“street”: “124 Updated Street”
},
“equipment”: {
“inverters”: […]
}
}
Delete Application
/api/v1/applications/{id}
applications:delete
Deletes a draft application. Only draft status applications can be deleted.
Submit Application
/api/v1/applications/{id}/submit
applications:submit
Submits a draft application for processing. For paper submissions, this generates DNO documents (G98/G99 forms, etc.).
Response (Paper Submission)
“message”: “Application submitted and documents generated”,
“status”: “submitted”,
“documentsGenerated”: 3,
“documents”: [
{ “name”: “G98-Application.pdf”, “type”: “G98”, “dno”: “UK Power Networks” },
{ “name”: “LOA.pdf”, “type”: “LOA”, “dno”: “” },
{ “name”: “SLD.pdf”, “type”: “SLD”, “dno”: “” }
]
}
Bulk Create Applications
/api/v1/applications/bulk
bulk:import
Create up to 100 applications in a single request.
“applications”: [
{ “applicationType”: “solar_pv”, “applicant”: {…}, “site”: {…}, … },
{ “applicationType”: “heat_pump”, “applicant”: {…}, “site”: {…}, … }
]
}
5. Status Management
Get Application Status
/api/v1/applications/{id}/status
applications:read
Returns current status, available transitions, and status history.
“currentStatus”: “submitted”,
“allowedTransitions”: [“documents_sent”, “pending_dno”, “withdrawn”],
“lastUpdated”: “2024-01-15T12:00:00Z”,
“documentsGeneratedAt”: “2024-01-15T10:30:00Z”,
“submissionErrors”: null,
“statusHistory”: [
{ “status”: “submitted”, “details”: {…}, “timestamp”: “2024-01-15T10:30:00Z” },
{ “status”: “draft”, “details”: null, “timestamp”: “2024-01-15T09:00:00Z” }
]
}
Update Application Status
/api/v1/applications/{id}/status
status:write
Allowed Status Transitions
| From Status | Allowed Transitions |
|---|---|
| draft | submitted, withdrawn |
| submitted | documents_sent, pending_dno, generation_failed, withdrawn |
| documents_sent | pending_dno, withdrawn |
| pending_dno | more_info_required, withdrawn |
| generation_failed | submitted, withdrawn |
| more_info_required | pending_dno, withdrawn |
approved, rejected, completed, commissioned. These are set by administrators or DNO responses.“status”: “documents_sent”,
“notes”: “Documents emailed to DNO”
}
6. Document Management
List Documents
/api/v1/applications/{id}/documents
documents:read
“uploaded”: [
{
“id”: “doc-uuid”,
“name”: “cutout_photo.jpg”,
“type”: “cutout_image”,
“size”: 245760,
“mimeType”: “image/jpeg”,
“uploadedAt”: “2024-01-15T11:00:00Z”
}
],
“generated”: [
{
“id”: “gen-doc-uuid”,
“name”: “G98-Application.pdf”,
“type”: “generated”,
“dno”: “UK Power Networks”,
“path”: “uploads/applications/app-id/g98.pdf”
}
]
}
Download Document
/api/v1/applications/{id}/documents/{documentId}
documents:read
Returns the document file as binary with appropriate Content-Type header.
Upload Document
/api/v1/applications/{id}/documents
documents:write
Upload a document using multipart/form-data:
| Field | Type | Description |
|---|---|---|
| file | file | Required The document file (max 10MB) |
| type | string | Optional Document type (cutout_image, mcs_certificate, etc.) |
Allowed file types: JPEG, PNG, GIF, PDF, Word documents, Excel spreadsheets
Delete Document
/api/v1/applications/{id}/documents/{documentId}
documents:write
Regenerate Documents
/api/v1/applications/{id}/documents/generate
documents:generate
Regenerates DNO documents (G98/G99 forms) for paper submissions. Useful after updating application details.
7. Document Requests
Request specific documents from customers/applicants.
List Document Requests
/api/v1/applications/{id}/document-requests
document_requests:read
Create Document Request
/api/v1/applications/{id}/document-requests
document_requests:write
“documentType”: “mcs_certificate”,
“description”: “Please provide your MCS certificate for this installation”,
“deadline”: “2024-01-20T23:59:59Z”
}
Update Document Request
/api/v1/applications/{id}/document-requests/{requestId}
document_requests:write
“status”: “approved”, // pending, uploaded, approved, rejected
“rejectionReason”: “Document expired”
}
Upload for Document Request
/api/v1/applications/{id}/document-requests/{requestId}/upload
documents:write
Upload a document to fulfill a request using multipart/form-data.
8. Device Database
Search ENA approved devices (inverters, heat pumps, EV chargers).
Search Inverters
/api/v1/devices/inverters
devices:read
| Parameter | Type | Description |
|---|---|---|
| search | string | Search in model, manufacturer, ENA registration |
| manufacturer | string | Filter by manufacturer |
| category | string | Filter by category |
| limit | integer | Results (default: 50) |
Search Heat Pumps
/api/v1/devices/heatpumps
devices:read
Search EV Chargers
/api/v1/devices/evchargers
devices:read
Additional parameter: v2g=true to filter for V2G-capable chargers.
9. Installers API
Save installer/contractor details for reuse across applications.
List Installers
/api/v1/installers
installers:read
Create Installer
/api/v1/installers
installers:write
“companyName”: “Smith Solar Ltd”, // Required
“contactName”: “John Smith”,
“email”: “john@smithsolar.com”,
“phone”: “07700900123”,
“address”: “456 Business Park”,
“city”: “Manchester”,
“postcode”: “M1 1AA”,
“mcsNumber”: “MCS123456”
}
10. Error Handling
Error Response Format
“error”: “Validation failed”,
“message”: “MPAN must be 13 digits”,
“validTypes”: [“solar_pv”, “heat_pump”, …] // Additional context when relevant
}
HTTP Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request – Invalid parameters or validation failed |
| 401 | Unauthorized – Invalid or missing API key |
| 403 | Forbidden – Insufficient scope/permissions |
| 404 | Not Found – Resource doesn’t exist or not owned by you |
| 429 | Too Many Requests – Rate limit exceeded |
| 500 | Internal Server Error |
| 503 | Service Unavailable – Document generation service not configured |
11. Code Examples
cURL
curl -X GET “https://app.renewablehelp.co.uk/api/v1/applications?status=draft&limit=10” \
-H “X-API-Key: gf_live_your_api_key”
# Create application
curl -X POST “https://app.renewablehelp.co.uk/api/v1/applications” \
-H “X-API-Key: gf_live_your_api_key” \
-H “Content-Type: application/json” \
-d ‘{
“applicationType”: “solar_pv”,
“mpan”: “1234567890123”,
“applicant”: {
“firstName”: “John”,
“lastName”: “Smith”,
“email”: “john@example.com”
},
“site”: {
“street”: “123 Solar Street”,
“city”: “London”,
“postcode”: “SW1A 1AA”
},
“equipment”: {
“inverters”: [{
“manufacturer”: “SolarEdge”,
“model”: “SE5000H”,
“capacity”: 5.0
}]
}
}’
# Submit application
curl -X POST “https://app.renewablehelp.co.uk/api/v1/applications/{id}/submit” \
-H “X-API-Key: gf_live_your_api_key”
# Upload document
curl -X POST “https://app.renewablehelp.co.uk/api/v1/applications/{id}/documents” \
-H “X-API-Key: gf_live_your_api_key” \
-F “file=@/path/to/cutout.jpg” \
-F “type=cutout_image”
# Download document
curl -X GET “https://app.renewablehelp.co.uk/api/v1/applications/{id}/documents/{docId}” \
-H “X-API-Key: gf_live_your_api_key” \
–output document.pdf
JavaScript (Node.js)
const FormData = require(‘form-data’);
const fs = require(‘fs’);
const API_KEY = ‘gf_live_your_api_key’;
const BASE_URL = ‘https://app.renewablehelp.co.uk/api/v1’;
const api = axios.create({
baseURL: BASE_URL,
headers: { ‘X-API-Key’: API_KEY }
});
// List applications
async function listApplications(filters = {}) {
const response = await api.get(‘/applications’, { params: filters });
return response.data;
}
// Create application
async function createApplication(data) {
const response = await api.post(‘/applications’, data);
return response.data;
}
// Submit application
async function submitApplication(id) {
const response = await api.post(`/applications/${id}/submit`);
return response.data;
}
// Upload document
async function uploadDocument(appId, filePath, type) {
const form = new FormData();
form.append(‘file’, fs.createReadStream(filePath));
form.append(‘type’, type);
const response = await api.post(`/applications/${appId}/documents`, form, {
headers: form.getHeaders()
});
return response.data;
}
// Example usage
async function main() {
// Create and submit an application
const app = await createApplication({
applicationType: ‘solar_pv’,
mpan: ‘1234567890123’,
applicant: { firstName: ‘John’, lastName: ‘Smith’, email: ‘john@example.com’ },
site: { street: ‘123 Solar Street’, city: ‘London’, postcode: ‘SW1A 1AA’ },
equipment: { inverters: [{ manufacturer: ‘SolarEdge’, model: ‘SE5000H’, capacity: 5.0 }] }
});
console.log(‘Created:’, app.application.referenceNumber);
// Submit to generate documents
const result = await submitApplication(app.application.id);
console.log(‘Documents generated:’, result.documentsGenerated);
}
main().catch(console.error);
Python
API_KEY = ‘gf_live_your_api_key’
BASE_URL = ‘https://app.renewablehelp.co.uk/api/v1’
headers = {
‘X-API-Key’: API_KEY,
‘Content-Type’: ‘application/json’
}
def list_applications(**filters):
response = requests.get(f'{BASE_URL}/applications’, headers=headers, params=filters)
response.raise_for_status()
return response.json()
def create_application(data):
response = requests.post(f'{BASE_URL}/applications’, headers=headers, json=data)
response.raise_for_status()
return response.json()
def submit_application(app_id):
response = requests.post(f'{BASE_URL}/applications/{app_id}/submit’, headers=headers)
response.raise_for_status()
return response.json()
def upload_document(app_id, file_path, doc_type):
with open(file_path, ‘rb’) as f:
files = {‘file’: f}
data = {‘type’: doc_type}
response = requests.post(
f'{BASE_URL}/applications/{app_id}/documents’,
headers={‘X-API-Key’: API_KEY},
files=files,
data=data
)
response.raise_for_status()
return response.json()
# Example usage
if __name__ == ‘__main__’:
app = create_application({
‘applicationType’: ‘solar_pv’,
‘mpan’: ‘1234567890123’,
‘applicant’: {‘firstName’: ‘John’, ‘lastName’: ‘Smith’, ’email’: ‘john@example.com’},
‘site’: {‘street’: ‘123 Solar Street’, ‘city’: ‘London’, ‘postcode’: ‘SW1A 1AA’},
‘equipment’: {‘inverters’: [{‘manufacturer’: ‘SolarEdge’, ‘model’: ‘SE5000H’, ‘capacity’: 5.0}]}
})
print(f”Created: {app[‘application’][‘referenceNumber’]}”)
result = submit_application(app[‘application’][‘id’])
print(f”Documents generated: {result[‘documentsGenerated’]}”)
PHP
$apiKey = ‘gf_live_your_api_key’;
$baseUrl = ‘https://app.renewablehelp.co.uk/api/v1’;
function apiRequest($endpoint, $method = ‘GET’, $data = null) {
global $apiKey, $baseUrl;
$ch = curl_init();
$url = $baseUrl . $endpoint;
$headers = [“X-API-Key: $apiKey”];
if ($method === ‘POST’ || $method === ‘PUT’) {
$headers[] = ‘Content-Type: application/json’;
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
if ($method === ‘POST’) curl_setopt($ch, CURLOPT_POST, true);
if ($method === ‘PUT’) curl_setopt($ch, CURLOPT_CUSTOMREQUEST, ‘PUT’);
if ($method === ‘DELETE’) curl_setopt($ch, CURLOPT_CUSTOMREQUEST, ‘DELETE’);
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [‘code’ => $httpCode, ‘data’ => json_decode($response, true)];
}
// List applications
$result = apiRequest(‘/applications?status=draft&limit=10’);
print_r($result[‘data’]);
// Create application
$app = apiRequest(‘/applications’, ‘POST’, [
‘applicationType’ => ‘solar_pv’,
‘mpan’ => ‘1234567890123’,
‘applicant’ => [‘firstName’ => ‘John’, ‘lastName’ => ‘Smith’, ’email’ => ‘john@example.com’],
‘site’ => [‘street’ => ‘123 Solar Street’, ‘city’ => ‘London’, ‘postcode’ => ‘SW1A 1AA’],
‘equipment’ => [‘inverters’ => [[‘manufacturer’ => ‘SolarEdge’, ‘model’ => ‘SE5000H’, ‘capacity’ => 5.0]]]
]);
echo “Created: ” . $app[‘data’][‘application’][‘referenceNumber’] . “\n”;
// Submit
$appId = $app[‘data’][‘application’][‘id’];
$result = apiRequest(“/applications/$appId/submit”, ‘POST’);
echo “Documents generated: ” . $result[‘data’][‘documentsGenerated’] . “\n”;
Need Help?
If you have questions or need assistance with the API:
- Email: support@renewablehelp.co.uk
- Documentation: app.renewablehelp.co.uk/documentation
