# SubmitDock Comprehensive AI Agent & Developer Guide SubmitDock is a dedicated host for iOS app public submission pages. It lets developers and automated agents publish compliant Support Pages and Privacy Policy URLs required by Apple App Store Connect without maintaining servers or blog engines. ## 1. Features for Agents and Automations - **RESTful Endpoints**: Full CRUD support (`GET`, `POST`, `PATCH`, `PUT`, `DELETE`). - **Markdown (CommonMark & GFM)**: Markdown is parsed and styled on the server. HTML tags are stripped/escaped for security. - **Image Upload in JSON**: Upload screenshots and square app icons directly in JSON using Base64 string or Data URIs (`data:image/png;base64,...`). - **Multipart Upload**: Also supports standard `multipart/form-data` with binary file streams. - **Automatic TOC**: Headings (`#`, `##`, `###`) automatically generate a Table of Contents on the Privacy Policy page. - **Safe Authentication**: `editToken` is generated using cryptographically random bytes and stored as SHA-256 hash. Pass it via `Authorization: Bearer ` or `X-Edit-Token: `. - **CORS Enabled**: `Access-Control-Allow-Origin: *` is provided for browser-based extensions and frontend agents. --- ## 2. API Reference ### 2.1 Create Page `POST /api/pages` #### Request Headers: - `Content-Type: application/json` or `multipart/form-data` #### JSON Request Fields: - `appName` (string, required, max 120 chars): Name of the iOS App. - `developerName` (string, required, max 120 chars): Developer or Organization Name. - `supportEmail` (string, required, max 160 chars): Valid support email address. - `appDescription` (string, required, max 4000 chars): Markdown text describing the app. - `privacyPolicy` (string, required, max 40000 chars): Markdown text for Privacy Policy. - `supportContent` (string, optional, max 20000 chars): Additional Markdown for Support page (FAQ, troubleshooting guide, release notes). - `appStoreUrl` (string, optional, max 300 chars): URL starting with `https://apps.apple.com/`. - `appIcon` (object, optional): Square app icon (max 1 MB). - `name`: string (e.g. `"icon.png"`) - `data`: string (Base64 string or data URI) - `screenshots` (array of objects, optional, max 6 images, total up to 4MB in JSON): - `name`: string (e.g. `"screen1.png"`) - `data`: string (Base64 string or data URI) #### Success Response (201 Created): ```json { "id": "m1abcd-1234", "editToken": "sdk_aBcDeF123456...", "supportUrl": "https://example.com/support/m1abcd-1234", "privacyUrl": "https://example.com/privacy/m1abcd-1234", "note": "Store editToken securely. It is shown only once and is required for PATCH/PUT/DELETE.", "page": { "id": "m1abcd-1234", "appName": "...", "developerName": "...", "supportEmail": "...", "appStoreUrl": "...", "appDescription": "...", "supportContent": "...", "privacyPolicy": "...", "appIcon": { "url": "https://example.com/media/m1abcd-1234/icon-....png", "contentType": "image/png" }, "screenshots": [ { "name": "1-screen1.png", "url": "https://example.com/media/...", "contentType": "image/png" } ], "contentFormat": "markdown", "editable": true, "supportUrl": "...", "privacyUrl": "...", "createdAt": "2026-10-11T20:00:00.000Z", "updatedAt": "2026-10-11T20:00:00.000Z" } } ``` --- ### 2.2 Get Page `GET /api/pages/:id` Returns public information about the page (without editToken). --- ### 2.3 Partial Update (PATCH) `PATCH /api/pages/:id` #### Headers: - `Authorization: Bearer ` - `Content-Type: application/json` Only include fields you wish to change. Example: ```json { "appDescription": "Updated app description with **markdown**.", "supportContent": "## Updated FAQ\n- New support question added." } ``` To clear screenshots: ```json { "screenshots": [] } ``` To remove the app icon: ```json { "appIcon": null } ``` --- ### 2.4 Delete Page `DELETE /api/pages/:id` #### Headers: - `Authorization: Bearer ` Deletes the page record and purges all uploaded media files from Netlify Blobs storage. --- ### 2.5 Issue or Claim Edit Token for Existing Page (Preserve URLs) `POST /api/pages/:id/token` Use this endpoint when an AI agent needs to update an existing page (including pages created via web forms or legacy endpoints) without changing the App Store URLs (`/support/:id`, `/privacy/:id`). #### Authentication Options (use any of the following): 1. **Admin Master Password** (Recommended for service owners / deployment agents): - Header: `X-Admin-Password: ` - Can issue/re-issue tokens for ANY page at any time. 2. **Token Rotation**: - Header: `Authorization: Bearer ` - Rotates the secret token. #### Success Response (200 OK): ```json { "id": "lx0abcde-1234", "editToken": "sdk_new_secret_token...", "supportUrl": "https://example.com/support/lx0abcde-1234", "privacyUrl": "https://example.com/privacy/lx0abcde-1234", "message": "Edit token issued via admin authorization.", "page": { ... } } ``` Once obtained, immediately use this `editToken` with `PATCH /api/pages/:id` to update descriptions or upload new screenshots. --- ## 3. Code Examples for AI Agents ### Python Example ```python import base64 import requests with open("screenshot.png", "rb") as f: b64_image = base64.b64encode(f.read()).decode("utf-8") payload = { "appName": "HabitQuest", "developerName": "Studio Hino", "supportEmail": "support@example.com", "appDescription": "## Simple habit tracker\nStay consistent every day.", "privacyPolicy": "## Privacy Policy\n\nNo analytics or tracking are included.", "screenshots": [ { "name": "screenshot.png", "data": f"data:image/png;base64,{b64_image}" } ] } res = requests.post("https:///api/pages", json=payload) data = res.json() print("Support URL:", data["supportUrl"]) print("Privacy URL:", data["privacyUrl"]) print("Edit Token:", data["editToken"]) ``` ### TypeScript / Node.js (fetch) ```typescript import fs from "node:fs/promises"; const imageBuffer = await fs.readFile("screenshot.png"); const b64 = imageBuffer.toString("base64"); const res = await fetch("https:///api/pages", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ appName: "FocusDock", developerName: "Dev Studio", supportEmail: "help@focusdock.app", appDescription: "Pomodoro timer for macOS & iOS.", privacyPolicy: "We collect zero telemetry data.", screenshots: [ { name: "screen.png", data: `data:image/png;base64,${b64}` } ] }) }); const result = await res.json(); console.log("Created ID:", result.id); console.log("Edit token:", result.editToken); ``` ## Release workspace See /admin/releases and /downloads/submitdock-releasekit.zip. Registration is private. A release manifest is separate from a public page; saving a draft does not publish it. Review state includes source and observation date. Restoring a draft preserves current review observations. No API keys, edit tokens, review contact phone numbers, local paths, or commands belong in the hosted registry.