Welcome to Wise ๐
Introduction
Wise is an AI-powered service designed to understand, extract, and structure energy-related documents, with a strong focus on electricity bills and consumption records.
Instead of manually reading PDFs, copying values, or dealing with inconsistent formats, Wise uses artificial intelligence to convert raw energy documents into clean, structured, and reusable data that can be easily consumed by systems, teams, and automated workflows.
The Wise API gives you programmatic access to this intelligence, allowing you to integrate document processing and data extraction directly into your applications.
What Wise is built for
Wise is purpose-built to solve common problems in energy workflows, such as:
- Reading electricity bills from different formats and providers.
- Extracting key energy data (consumption, demand, periods, identifiers).
- Converting unstructured documents into standardized schemas ready for analysis.
- Keeping document histories organized, traceable, and reusable over time.
Common use cases
Wise is commonly used to:
- Build accurate consumption histories from multiple electricity bills.
- Prepare reliable inputs for solar, storage, and hybrid energy projects.
- Automate document ingestion for sales, engineering, and after-sales teams.
- Ensure teams work with consistent and validated data, not manual transcriptions.
Why use the API
By using the Wise API, you can:
- Upload energy documents and let Wise process them automatically.
- Retrieve structured AI-generated outputs instead of raw files.
- Integrate Wise into your own platforms, CRMs, or internal tools.
- Scale document processing without increasing manual effort.
Wise turns documents into data โ and the API is how you access that intelligence.
Interactive documentation: Visit the API Documentation at Swagger UI to explore and test endpoints.
Requirements
- Active Wise account.
- HTTP client (
curl, Postman, Insomnia) or your own SDK.
Environments & Base URL
-
Production
https://production.sunwise.ai/wise/ -
OpenAPI (Swagger)
https://production.sunwise.ai/wise/api/v1/openapi.json
Check the Swagger documentation for the complete list of endpoints and available parameters.
Authentication
The API uses Bearer Token authentication via the Authorization header.
Authorization: Bearer <YOUR_API_KEY>
Example headers:
Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/json
Accept: application/json
You can obtain your API key by authenticating with your Wise account credentials using the login endpoint.
Getting Started
The flow below represents what is currently available in the Wise API. For detailed behavior, request bodies, and responses, please refer to the Swagger documentation.
First Request
Replace <YOUR_API_KEY> with your actual token.
curl
curl -X GET "https://production.sunwise.ai/wise/api/v1/projects/me" \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-H "Accept: application/json"
Usage Examples
Python (requests)
import os
import requests
BASE_URL = "https://production.sunwise.ai/wise/api/v1"
API_KEY = os.getenv("WISE_API_KEY") or "<YOUR_API_KEY>"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Accept": "application/json",
"Content-Type": "application/json",
}
resp = requests.get(f"{BASE_URL}/projects/me", headers=headers, timeout=30)
resp.raise_for_status()
print(resp.json())
JavaScript (fetch)
const BASE_URL = "https://production.sunwise.ai/wise/api/v1";
const API_KEY = "<YOUR_API_KEY>";
async function main() {
const res = await fetch(`${BASE_URL}/projects/me`, {
method: "GET",
headers: {
Authorization: `Bearer ${API_KEY}`,
Accept: "application/json",
},
});
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${await res.text()}`);
}
const data = await res.json();
console.log(data);
}
main().catch(console.error);
Postman / Insomnia
- Open Swagger and copy the OpenAPI URL:
https://production.sunwise.ai/wise/api/v1/openapi.json - In Postman, go to Import โ Link โ and paste the OpenAPI URL.
- Create an environment variable called
WISE_API_KEYand reference it in the headers:Authorization: Bearer {{WISE_API_KEY}}
Real-Time Updates with WebSockets ๐
Wise provides real-time progress tracking for document processing through WebSockets. This allows your application to receive live updates as documents are being analyzed, giving your users instant feedback on the processing status.
Why use WebSockets?
When you upload a document to Wise, the AI processing happens asynchronously. Instead of polling the API repeatedly to check if the document is ready, you can open a WebSocket connection and receive instant notifications as the document moves through each processing stage.
This is especially useful for:
- Building progress indicators in your UI.
- Providing real-time feedback to users during uploads.
- Detecting failures immediately without waiting for polling intervals.
- Creating a more responsive and modern user experience.
How it works
- Upload documents to a project using the REST API.
- Open a WebSocket connection to the project's channel.
- Receive real-time messages as documents are processed.
- Close the connection when processing is complete or when you no longer need updates.
The WebSocket uses Redis Pub/Sub under the hood to broadcast messages, ensuring reliable and scalable real-time communication.
WebSocket Endpoint
ws://production.sunwise.ai/wise/ws/{project_id}
Parameters:
Parameter Type Description
----------- ------ --------------------------------------------------
project_id UUID The unique identifier of the project to monitor.
Note: The project must exist before opening a WebSocket connection. If the project does not exist, the connection will be rejected with a 404 error.
Message Format
All messages sent through the WebSocket follow this JSON structure:
{
"attempt": 0,
"stage": 4,
"document_id": "550e8400-e29b-41d4-a716-446655440000",
"document": "electricity_bill_january.pdf",
"status": "success"
}
Fields:
Field Type Description
------------- -------- --------------------------------------------------------------------
attempt int The retry attempt number (starts at 0).
stage int The current processing stage (see table below).
document_id string The unique identifier of the document being processed.
document string The filename of the document.
status string Either "success" (processing normally) or "error" (processing failed).
Processing Stages
The stage field indicates where the document is in the processing pipeline:
Stage Name Description
------ ------------------------- ----------------------------------------------------------
0 UPLOADING_DOCUMENT Document is being uploaded to storage.
1 DOCUMENT_UPLOADED Document has been successfully uploaded.
2 START_DOCUMENT_FETCHING System is retrieving the document for processing.
3 START_TEXT_DECODING Extracting text or images from the document.
4 START_COMPLETION AI model is analyzing and extracting data from the document.
5 MERGING_PAGES Combining results from multiple pages into a single output.
6 START_SAVING_DOCUMENT Saving the extracted data to the database.
7 FINISHED Processing completed successfully.
-1 FAILED Processing encountered an error and could not complete.
Connection Examples
Python (websockets library)
import asyncio
import json
import websockets
async def listen_to_project(project_id: str):
uri = f"wss://production.sunwise.ai/wise/ws/{project_id}"
async with websockets.connect(uri) as websocket:
print("โ
Connected to Wise WebSocket")
async for message in websocket:
data = json.loads(message)
print(f"๐ Document: {data['document']}")
print(f"๐ Stage: {data['stage']}")
print(f"โ
Status: {data['status']}")
if data["stage"] == 7:
print("๐ Processing complete!")
break
if data["stage"] == -1:
print("โ Processing failed!")
break
# Run the listener
project_id = "550e8400-e29b-41d4-a716-446655440000"
asyncio.run(listen_to_project(project_id))
Building a Progress Bar
Here's an example of how to use the stage information to build a progress bar:
const STAGES = {
0: { name: "Uploading", progress: 10 },
1: { name: "Uploaded", progress: 20 },
2: { name: "Fetching", progress: 30 },
3: { name: "Decoding", progress: 45 },
4: { name: "Analyzing", progress: 60 },
5: { name: "Merging", progress: 75 },
6: { name: "Saving", progress: 90 },
7: { name: "Complete", progress: 100 },
"-1": { name: "Failed", progress: 0 },
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
const stage = STAGES[data.stage];
// Update your UI
updateProgressBar(stage.progress);
updateStatusText(`${stage.name}: ${data.document}`);
if (data.status === "error") {
showErrorNotification(`Failed to process ${data.document}`);
}
};
Best Practices
-
Handle disconnections gracefully โ WebSocket connections can drop. Implement reconnection logic with exponential backoff.
-
Close connections when done โ Don't leave WebSocket connections open unnecessarily. Close them when processing is complete or when the user navigates away.
-
Validate the project exists โ Before opening a WebSocket, verify the project exists using the REST API to avoid unnecessary connection attempts.
-
Use secure connections โ Always use
wss://(WebSocket Secure) in production environments. -
Handle multiple documents โ A project can have multiple documents. Use the
document_idfield to track the progress of each document individually.
Error Handling
If a document fails to process, you will receive a message with:
{
"attempt": 0,
"stage": -1,
"document_id": "550e8400-e29b-41d4-a716-446655440000",
"document": "corrupted_file.pdf",
"status": "error"
}
Common reasons for failures include:
- Unsupported file format โ The document is not a valid PDF or image.
- Corrupted file โ The file is damaged and cannot be read.
- AI processing error โ The AI model encountered an issue extracting data.
- Timeout โ The document took too long to process.
When you receive a FAILED status, you can retrieve more details by calling the project documents endpoint or retrying the upload.
Next Steps
- Review the API Documentation in Swagger and identify the endpoints you need.
- Test endpoints using Try it out and copy the generated
curlcommands. - Integrate the API into your application using Python, JavaScript, or your preferred language.
- If you have any questions about permissions, schemas, or general usage, reach out to Support.
Support
- Developer portal: Swagger Docs
- Contact: Contact page