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.

Example
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:

1. Read a file (curl)
curl "https://whatimade.app/v1/files/download?siteId=YOUR_SITE_ID&path=index.html" \
  -H "X-API-Key: wim_your_key_here"
2. Upload an updated file (curl)
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

Read, modify, and upload
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.

HeaderRequiredDescription
X-API-KeyYesYour API key
Response
{
  "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.

ParameterRequiredDescription
siteIdYesThe site ID (from verify endpoint)
prefixNoFilter by folder path (e.g. css/)
Response
{
  "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.

ParameterRequiredDescription
siteIdYesThe site ID
pathYesFile 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.

HeaderRequiredDescription
X-API-KeyYesYour API key
X-Site-IDYesThe site ID
Form FieldRequiredDescription
fileYesThe file to upload
pathNoTarget path on the site (defaults to the filename)
Response
{
  "success": true,
  "path": "index.html",
  "size": 2048,
  "contentType": "text/html"
}

Delete File

DELETE /v1/files/delete

Remove a file from the site.

HeaderRequiredDescription
X-API-KeyYesYour API key
X-Site-IDYesThe site ID
Request Body (JSON)
{ "path": "old-page.html" }
Response
{ "success": true }

Site Info

GET /v1/keys/sites

Get full details about the site associated with your API key.

Response
{
  "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"
  }
}
StatusCodeMeaning
400BAD_REQUESTMissing or invalid parameters
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENKey doesn't have access to the requested site
404NOT_FOUNDSite or file not found
429RATE_LIMITEDToo many requests (see Rate Limits)

Rate Limits

To keep the service fast for everyone, requests are rate limited per IP address:

EndpointLimit
File uploads20 per minute
API requests100 per minute
Deploys5 per minute

When rate limited, you'll receive a 429 response. Wait and try again.