# API with cURL Complete guide to tingz API with cURL. ## Assumptions - Running deployer service on http://localhost:8080 - Admin token (set in `.env.development` as `ADMIN_TOKEN`) set to `devadmintoken` - API version is `v1` ## Step 1: Create a User (Admin Only) First, an admin needs to create a user account to get a deployment token. ```bash curl -X POST "http://localhost:8080/api/v1/auth" \ -H "Authorization: Bearer devadmintoken" \ -H "Content-Type: application/json" \ -d '{"username":"alice"}' ``` **Success Response:** ```json { "status": "ok", "token": "82lz0BVOWtV4uVj9DBZBuKMeyVDwidL2" } ``` **Important:** Save this token! You'll need it for all deployments for that user. ### Username Requirements - Lowercase letters, numbers, hyphens, underscores only - 1-64 characters - Must start and end with alphanumeric character - Pattern: `^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$` ## Step 2: Prepare Your Static Site Package your static site as a `.tar.gz` file with files at the root level. ### Correct Way (Files at Root) ```bash cd /path/to/your/site tar -czf ../site.tar.gz . ``` This creates a tarball where `index.html` is at the root, not nested in a directory. ### What NOT to Do ```bash # DON'T: This creates site/index.html (nested) tar -czf site.tar.gz site/ # DON'T: This creates /path/to/your/site/index.html (nested) tar -czf site.tar.gz /path/to/your/site ``` ### Verify Your Tarball ```bash tar -tzf site.tar.gz | head -5 ``` Expected output: ``` index.html css/ css/style.css js/ js/app.js ``` NOT: ``` site/index.html ← Wrong! Nested directory site/css/style.css ``` ## Step 3: Deploy Your Site Use your user token to deploy the site. ```bash curl -X POST "http://localhost:8080/api/v1/deploy" \ -H "Authorization: Bearer YOUR_USER_TOKEN" \ -F "project=myproject" \ -F "file=@site.tar.gz" ``` **Success Response:** ```json { "status": "ok", "project": "myproject", "username": "alice", "url": "https://docs.yigid.dev/alice/myproject/", "release": "20251014T180806" } ``` ### Project Name Requirements - Same rules as username - Lowercase, alphanumeric, hyphens, underscores - 1-64 characters - Pattern: `^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$` ### Important Notes - The `@` prefix is required for file uploads: `-F "file=@site.tar.gz"` - Max upload size: 100MB (default, configurable) - Files are deployed to: `/var/www/docs/{username}/{project}/` - Each deployment creates a new release in `/var/www/deploys/{username}/{project}/{release_id}/` - The deploy directory is an atomic symlink to the latest release - Old releases are kept (5 by default) for rollback ## Step 4: Verify Deployment ### Check the Symlink ```bash ls -la docs/alice/myproject ``` Output: ``` lrwxr-xr-x 1 deployer deployer 47 Oct 14 21:08 myproject -> /var/www/deploys/alice/myproject/20251014T180806 ``` ### Check the Files ```bash ls -la deploys/alice/myproject/20251014T180806/ ``` ### Access Your Site ```bash curl http://localhost:8080/alice/myproject/ # or curl https://docs.yigid.dev/alice/myproject/ ``` ## Complete Workflow Example ```bash # 1. Set your admin token export ADMIN_TOKEN="devadmintoken" # 2. Create user and capture token USER_TOKEN=$(curl -s -X POST "http://localhost:8080/api/v1/auth" \ -H "Authorization: Bearer ${ADMIN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"username":"alice"}' | jq -r '.token') echo "User token: ${USER_TOKEN}" # 3. Create test site mkdir -p my-site cat > my-site/index.html << 'EOF' My Site

Hello, World!

EOF # 4. Package site tar -czf site.tar.gz -C my-site . # 5. Deploy curl -s -X POST "http://localhost:8080/api/v1/deploy" \ -H "Authorization: Bearer ${USER_TOKEN}" \ -F "project=mysite" \ -F "file=@site.tar.gz" | jq # 6. Verify curl http://localhost:8080/alice/mysite/ ``` ## Health Check Test if the service is running: ```bash curl http://localhost:8080/api/v1/status ``` Expected response: ```json { "status": "ok" } ``` ## Error Responses ### Invalid Token ```json { "status": "error", "error": "unauthorized" } ``` ### Invalid Project Name ```json { "status": "error", "error": "invalid project name format" } ``` ### Missing File ```json { "status": "error", "error": "missing or invalid file" } ``` ### Upload Too Large ```json { "status": "error", "error": "request body too large" } ``` ### Path Traversal in Tarball ```json { "status": "error", "error": "failed to extract tarball: path contains '..' component which is not allowed: ../../etc/passwd" } ``` ## User Management (Admin Only) ### Reroll User Token Create a new token for an existing user (invalidates old token): ```bash curl -X POST "http://localhost:8080/api/v1/auth" \ -H "Authorization: Bearer ${ADMIN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"username":"alice"}' ``` ### Delete User (Keep Files) ```bash curl -X DELETE "http://localhost:8080/api/v1/auth" \ -H "Authorization: Bearer ${ADMIN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"username":"alice","files":"persist"}' ``` ### Delete User and All Files ```bash curl -X DELETE "http://localhost:8080/api/v1/auth" \ -H "Authorization: Bearer ${ADMIN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"username":"alice","files":"delete"}' ``` ## CI/CD Integration ### GitHub Actions ```yaml name: Deploy Documentation on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build site run: | # Your build steps here npm run build - name: Package and deploy env: DEPLOYER_TOKEN: ${{ secrets.DEPLOYER_TOKEN }} run: | tar -czf site.tar.gz -C dist . curl -f -X POST "https://deployer.example.com/api/v1/deploy" \ -H "Authorization: Bearer ${DEPLOYER_TOKEN}" \ -F "project=docs" \ -F "file=@site.tar.gz" ``` ### GitLab CI ```yaml deploy: stage: deploy only: - main script: - tar -czf site.tar.gz -C public . - | curl -f -X POST "https://deployer.example.com/api/v1/deploy" \ -H "Authorization: Bearer ${DEPLOYER_TOKEN}" \ -F "project=docs" \ -F "file=@site.tar.gz" variables: DEPLOYER_TOKEN: $DEPLOYER_TOKEN ``` ## Tips & Best Practices 1. **Always use `@` for file uploads**: `-F "file=@your-file.tar.gz"` 2. **Verify tarball contents** before deploying: ```bash tar -tzf site.tar.gz | head -20 ``` 3. **Use `-f` flag in CI/CD** to fail on HTTP errors: ```bash curl -f -X POST ... ``` 4. **Pretty-print JSON responses** with `jq`: ```bash curl ... | jq ``` 5. **Avoid macOS resource forks** in tarballs: ```bash COPYFILE_DISABLE=1 tar -czf site.tar.gz -C dist . ``` 6. **Check release history**: ```bash ls -lt deploys/alice/myproject/ ``` 7. **Atomic deployments**: The symlink swap is atomic, so no downtime during deployment 8. **Release retention**: Old releases are kept (5 by default) for manual rollback if needed