API Documentation
Let any AI assistant read and edit files on your WhatIMade site. Works with ChatGPT, Claude, Gemini, and any tool that can make HTTP requests.
Overview
The WhatIMade API lets you programmatically manage files on any hosted site. The primary use case is giving AI assistants access to your website so they can read, edit, and publish changes on your behalf.
Base URL: https://whatimade.app/v1
All responses are JSON. All requests use standard HTTP methods.
Authentication
Create an API key from your site's AI Access tab in the dashboard. Pass it via the X-API-Key header on every request.
Keep your key secret. Anyone with your API key can read and modify your site files. You can revoke a key at any time from the dashboard.
curl https://whatimade.app/v1/keys/verify \
-H "X-API-Key: wim_your_key_here"
Quick Start
Here's how to read a file and then upload a change:
curl "https://whatimade.app/v1/files/download?siteId=YOUR_SITE_ID&path=index.html" \
-H "X-API-Key: wim_your_key_here"
curl -X POST https://whatimade.app/v1/files/upload \
-H "X-API-Key: wim_your_key_here" \
-H "X-Site-ID: YOUR_SITE_ID" \
-F "file=@index.html" \
-F "path=index.html"
Python Example
import requests
API_KEY = "wim_your_key_here"
SITE_ID = "YOUR_SITE_ID"
BASE = "https://whatimade.app/v1"
HEADERS = {"X-API-Key": API_KEY}
# Read a file
r = requests.get(f"{BASE}/files/download",
params={"siteId": SITE_ID, "path": "index.html"},
headers=HEADERS)
html = r.text
# Modify it
html = html.replace("Hello", "Hello World")
# Upload the updated version
requests.post(f"{BASE}/files/upload",
headers={**HEADERS, "X-Site-ID": SITE_ID},
files={"file": ("index.html", html, "text/html")},
data={"path": "index.html"})
Give Your AI These Instructions
Copy and paste this into ChatGPT, Claude, or any AI assistant:
I have a website hosted on WhatIMade.app.
You can read and edit my site files using these details:
API Key: wim_your_key_here
Site ID: YOUR_SITE_ID
Base URL: https://whatimade.app/v1
Endpoints:
- GET /files/list?siteId={id} (list all files)
- GET /files/download?siteId={id}&path={path} (read a file)
- POST /files/upload with X-Site-ID header (upload a file)
- DELETE /files/delete with X-Site-ID header (delete a file)
Always include the header: X-API-Key: wim_your_key_here
Verify Key
GET /v1/keys/verify
Check if your API key is valid and get the site it's associated with.
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your API key |
{
"valid": true,
"site": {
"id": "abc123",
"subdomain": "my-portfolio",
"access_type": "public"
},
"key": {
"id": "key123",
"name": "ChatGPT access",
"last_used_at": 1713206400000
}
}
List Files
GET /v1/files/list?siteId={id}
List all files and folders in a site.
| Parameter | Required | Description |
|---|---|---|
siteId | Yes | The site ID (from verify endpoint) |
prefix | No | Filter by folder path (e.g. css/) |
{
"files": [
{
"key": "index.html",
"size": 2048,
"contentType": "text/html"
},
{
"key": "css/style.css",
"size": 512,
"contentType": "text/css"
}
],
"folders": [
{ "prefix": "css" },
{ "prefix": "images" }
]
}
Read File
GET /v1/files/download?siteId={id}&path={path}
Download the contents of a specific file. Returns the raw file content with the appropriate Content-Type header.
| Parameter | Required | Description |
|---|---|---|
siteId | Yes | The site ID |
path | Yes | File path (e.g. index.html or css/style.css) |
Upload File
POST /v1/files/upload
Upload or replace a file on the site. Uses multipart form data.
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your API key |
X-Site-ID | Yes | The site ID |
| Form Field | Required | Description |
|---|---|---|
file | Yes | The file to upload |
path | No | Target path on the site (defaults to the filename) |
{
"success": true,
"path": "index.html",
"size": 2048,
"contentType": "text/html"
}
Delete File
DELETE /v1/files/delete
Remove a file from the site.
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your API key |
X-Site-ID | Yes | The site ID |
{ "path": "old-page.html" }
{ "success": true }
Site Info
GET /v1/keys/sites
Get full details about the site associated with your API key.
{
"site": {
"id": "abc123",
"subdomain": "my-portfolio",
"custom_domain": null,
"created_at": 1713206400000,
"updated_at": 1713206400000,
"access_type": "public",
"title": "My Portfolio",
"description": null
}
}
Errors
All errors return a JSON object with an error field:
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
}
}
| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Missing or invalid parameters |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | FORBIDDEN | Key doesn't have access to the requested site |
| 404 | NOT_FOUND | Site or file not found |
| 429 | RATE_LIMITED | Too many requests (see Rate Limits) |
Rate Limits
To keep the service fast for everyone, requests are rate limited per IP address:
| Endpoint | Limit |
|---|---|
| File uploads | 20 per minute |
| API requests | 100 per minute |
| Deploys | 5 per minute |
When rate limited, you'll receive a 429 response. Wait and try again.