# 🔧 GITEA API PATTERNS — Cookbook for Future Claudes

**Document ID:** FFG-CORE-GITEA
**Version:** 1.0
**Status:** CURRENT
**Created:** February 13, 2026
**Created By:** Chronicler the Fifth

---

## Purpose

This document contains tested, efficient patterns for working with the Gitea API. Every future Claude should read this before making API calls. These patterns were discovered through trial and optimization — use them.

---

## The Golden Rule

**One commit > Many commits**

Every API call burns context. Batch operations whenever possible.

---

## Pattern 1: Multi-File Commit (CRITICAL)

**Endpoint:** `POST /repos/{owner}/{repo}/contents`

**Use this when:** You need to create, update, or delete multiple files. This is almost always.

**Instead of:**
```
# BAD - 6 API calls for 3 files
GET file1 SHA → PUT file1 → GET file2 SHA → PUT file2 → GET file3 SHA → PUT file3
```

**Do this:**
```
# GOOD - 1 API call for 3 files
POST /contents with files array
```

**Format:**
```json
{
  "message": "Descriptive commit message",
  "files": [
    {
      "operation": "create",
      "path": "path/to/new-file.md",
      "content": "base64-encoded-content"
    },
    {
      "operation": "update",
      "path": "path/to/existing-file.md",
      "content": "base64-encoded-content",
      "sha": "current-file-sha"
    },
    {
      "operation": "delete",
      "path": "path/to/delete-me.md",
      "sha": "current-file-sha"
    }
  ]
}
```

**Operations:**
- `create` — New file (no SHA needed)
- `update` — Modify existing file (SHA required)
- `delete` — Remove file (SHA required)

**Bash example:**
```bash
cat > /home/claude/commit.json << 'EOF'
{
  "message": "Update multiple docs",
  "files": [
    {"operation": "create", "path": "docs/new.md", "content": "BASE64HERE"},
    {"operation": "update", "path": "docs/existing.md", "content": "BASE64HERE", "sha": "abc123"}
  ]
}
EOF

curl -s -X POST \
  -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  "https://git.firefrostgaming.com/api/v1/repos/firefrost-gaming/firefrost-operations-manual/contents" \
  -d @/home/claude/commit.json
```

**Efficiency gain:** 3 files × 2 calls each = 6 calls → 1 call = **83% reduction**

---

## Pattern 2: SHA Cache

**Problem:** Every update requires the current file SHA. Fetching it costs an API call.

**Solution:** Cache SHAs in session-handoff.md. Use them for first update. Track new SHAs after each push.

**Location:** `docs/core/session-handoff.md` → SHA Cache section

**Workflow:**
1. Read SHA from cache (no API call)
2. Push update with cached SHA
3. Response includes new SHA
4. Track new SHA locally for subsequent updates
5. Update cache at session end

**If push fails (409 conflict):** SHA is stale. Fetch once, retry.

---

## Pattern 3: Front-Load Reads

**Problem:** Reading files mid-session burns context repeatedly.

**Solution:** Read everything you need at session start. Work from memory.

**Session start reads:**
1. Essence Patch (required, full)
2. Relationship Context (required, full)
3. Quick Start or Session Handoff (efficiency docs)
4. Tasks (if doing task work)

**During session:** Draft locally, push when ready. Don't re-read to "check" files.

---

## Pattern 4: Local Drafting

**Problem:** Iterating through the API wastes calls on drafts.

**Solution:** Draft in artifacts or local files. Get approval. Push once.

**Workflow:**
```
1. Draft content in /home/claude/filename.md
2. Show Michael for review (in chat or artifact)
3. Iterate until approved
4. Base64 encode: base64 -w 0 /home/claude/filename.md
5. Push via API (single call, or batch with multi-file)
```

**Base64 encoding:**
```bash
# Single file
CONTENT=$(base64 -w 0 /home/claude/myfile.md)

# Use in JSON
echo "{\"content\": \"$CONTENT\"}"
```

---

## Pattern 5: Batch Related Changes

**Principle:** If changes are logically related, commit them together.

**Examples:**
- Updating a protocol + updating docs that reference it = 1 commit
- Creating templates (3 files) = 1 commit
- Session close (memorial + summary + SHA cache update) = 1 commit

**Don't batch:** Unrelated changes. Keep commits atomic and meaningful.

---

## Pattern 6: Raw File Read (When Needed)

**Endpoint:** `GET /repos/{owner}/{repo}/raw/{branch}/{path}`

**Use when:** You need file contents without metadata.

**Advantage:** Returns raw content directly (no JSON parsing, no base64 decoding).

**Example:**
```bash
curl -s -H "Authorization: token $TOKEN" \
  "https://git.firefrostgaming.com/firefrost-gaming/firefrost-operations-manual/raw/branch/master/docs/core/tasks.md"
```

**Note:** Doesn't return SHA. Use when you only need to read, not update.

---

## Pattern 7: Get SHA Only

**Endpoint:** `GET /repos/{owner}/{repo}/contents/{path}`

**Use when:** You need SHA but not full content (rare — use cache instead).

**Parse SHA:**
```bash
curl -s -H "Authorization: token $TOKEN" \
  "https://git.firefrostgaming.com/api/v1/repos/firefrost-gaming/firefrost-operations-manual/contents/docs/core/tasks.md" \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['sha'])"
```

---

## API Reference Quick Card

| Action | Endpoint | Method |
|:-------|:---------|:-------|
| Multi-file commit | `/repos/{owner}/{repo}/contents` | POST |
| Read file (with metadata) | `/repos/{owner}/{repo}/contents/{path}` | GET |
| Read file (raw) | `/repos/{owner}/{repo}/raw/{branch}/{path}` | GET |
| Create single file | `/repos/{owner}/{repo}/contents/{path}` | POST |
| Update single file | `/repos/{owner}/{repo}/contents/{path}` | PUT |
| Delete single file | `/repos/{owner}/{repo}/contents/{path}` | DELETE |
| List directory | `/repos/{owner}/{repo}/contents/{path}` | GET |
| Check version | `/version` | GET |

**Base URL:** `https://git.firefrostgaming.com/api/v1`
**Auth:** `Authorization: token <TOKEN>`

---

## Efficiency Checklist

Before making API calls, ask:

- [ ] Can I batch these into one multi-file commit?
- [ ] Do I have the SHA cached already?
- [ ] Am I re-reading something already in context?
- [ ] Am I pushing a draft, or final content?
- [ ] Is this the gut check moment? (Push now vs batch)

---

## Common Mistakes to Avoid

1. **Reading to "verify"** — Trust what's in context
2. **One commit per file** — Use multi-file endpoint
3. **Fetching SHA every time** — Use cache
4. **Iterating through API** — Draft locally first
5. **Forgetting to track new SHAs** — Update after every push

---

## Tested On

- **Gitea Version:** 1.21.5
- **Date Tested:** February 13, 2026
- **Tested By:** Chronicler the Fifth

Multi-file commit endpoint confirmed working. All patterns validated.

---

*"One commit > Many commits. Every call costs context."*

🔥❄️💙
