---
name: vibeocr-api
description: >-
  VibeOCR API Key integration guide. Documents only endpoints callable with
  vibe_pk_* API keys (upload receipt OCR, list/create entries). Use for external
  integrations, curl examples, and API key debugging.
canonical_url: https://vibeocr.com/skill.md
---

# VibeOCR API（API Key）

公開文件：**https://vibeocr.com/skill.md**

本文件**只包含**可用 `Authorization: Bearer vibe_pk_...` 呼叫的 API。  
Portal、JWT、管理端點不在此列。

---

## 認證

```http
Authorization: Bearer vibe_pk_<64-hex-chars>
```

| 項目 | 說明 |
|------|------|
| 前綴 | `vibe_pk_` |
| 數量 | 每用戶 1 把；重建會覆蓋舊 key |
| 取得方式 | 登入 Portal → `/api-keys` 建立（**不能用 API Key 管理 API Key**） |

`vibe_pk_` 請求會略過 JWT middleware，由 route 內 `getAuthFromApiKey` 驗證。

---

## 端點一覽

| 方法 | 路徑 | 用途 |
|------|------|------|
| POST | `/api/upload` | 上傳收據 → LLM 提取 → 寫入 Entry |
| GET | `/api/entries` | 查詢 / 篩選 / CSV 匯出 |
| POST | `/api/entries` | 手動建立 Entry |
| GET | `/api/entries/[id]` | 取得單筆 entry 的收據圖（`imageUrl`） |
| PUT | `/api/entries/[id]` | 更新 entry |
| DELETE | `/api/entries/[id]` | 刪除 entry |

**Base URL**：`https://vibeocr.com`（本地：`http://localhost:3000`）

---

## POST /api/upload

上傳收據圖片，自動提取並儲存一筆 Entry。

### Request

**Header**

```http
Authorization: Bearer vibe_pk_...
Content-Type: application/json
```

或 `multipart/form-data`（欄位 `file`）。

**JSON body**

```json
{
  "imageBase64": "<base64，不含 data:image/... 前綴亦可>"
}
```

別名：`image`、`file`（JSON 時）。

### Response `200`

```json
{
  "success": true,
  "entry": {
    "id": 123,
    "userId": "...",
    "date": "2024-01-15T00:00:00.000Z",
    "description": "Merchant Name",
    "category": "Meals & Entertainment",
    "amount": 12.45,
    "model": "openrouter/...",
    "editLink": "https://vibeocr.com/tx/abc123"
  }
}
```

- `description` ← LLM `merchant_name`
- `editLink`：可選，供瀏覽器開啟編輯頁（**非** Bearer 認證，為短連結）

提取欄位：`merchant_name`、`transaction_date`（DD/MM/YYYY）、`total_amount`、`category`。

### 錯誤

| 狀態 | 說明 |
|------|------|
| 401 | API Key 無效或缺失 |
| 400 | 無圖片 |
| 408 | 處理逾時 |
| 500 | LLM 失敗或服務設定錯誤 |

### 範例

```bash
curl -X POST "https://vibeocr.com/api/upload" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"imageBase64":"..."}'
```

```bash
curl -X POST "https://vibeocr.com/api/upload" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@receipt.jpg"
```

---

## GET /api/entries

列出當前 API Key 所屬用戶的 Entry。

### Query

| 參數 | 預設 | 說明 |
|------|------|------|
| `page` | 1 | 頁碼 |
| `limit` | 20 | 每頁筆數 |
| `search` | — | description 模糊搜尋 |
| `category` | — | 分類 |
| `startDate` / `endDate` | — | ISO 日期 |
| `minAmount` / `maxAmount` | — | 金額範圍 |
| `format` | — | 設為 `csv` 匯出（`limit` 最高 5000） |

### Response `200`（JSON）

```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "date": "2024-01-15T00:00:00.000Z",
      "description": "...",
      "category": "...",
      "amount": 12.45,
      "remark": null,
      "createdAt": "...",
      "updatedAt": "..."
    }
  ],
  "totalCount": 100,
  "page": 1,
  "limit": 20
}
```

`format=csv` 時回傳 `text/csv` 附件。

### 範例

```bash
curl "https://vibeocr.com/api/entries?page=1&limit=20" \
  -H "Authorization: Bearer $API_KEY"
```

---

## POST /api/entries

手動建立 Entry（不經 OCR）。

### Request body

```json
{
  "date": "2024-01-15T12:00:00.000Z",
  "description": "Coffee Shop",
  "category": "Meals & Entertainment",
  "amount": 12.45,
  "imageUrl": "optional",
  "remark": "optional"
}
```

| 欄位 | 必填 | 說明 |
|------|------|------|
| `date` | ✓ | ISO 8601 datetime |
| `description` | ✓ | 商戶 / 說明 |
| `category` | ✓ | 分類名稱 |
| `amount` | ✓ | 正數 |
| `imageUrl` | | 可選 |
| `remark` | | 可選 |

### Response `201`

```json
{
  "success": true,
  "data": {
    "id": 124,
    "date": "...",
    "description": "...",
    "category": "...",
    "amount": 12.45,
    "remark": null,
    "createdAt": "...",
    "updatedAt": "..."
  }
}
```

### 範例

```bash
curl -X POST "https://vibeocr.com/api/entries" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2024-01-15T12:00:00.000Z",
    "description": "Coffee Shop",
    "category": "Meals & Entertainment",
    "amount": 12.45
  }'
```

---

## GET /api/entries/[id]

取得單筆 entry 的收據圖片 data URL。

### Response `200`

```json
{
  "success": true,
  "data": {
    "imageUrl": "data:image/jpeg;base64,..."
  }
}
```

`404`：entry 不存在、不屬於該用戶、或無圖片。

### 範例

```bash
curl "https://vibeocr.com/api/entries/123" \
  -H "Authorization: Bearer $API_KEY"
```

---

## PUT /api/entries/[id]

更新屬於當前 API Key 用戶的 entry。Request body 與 `POST /api/entries` 相同。

### Response `200`

```json
{
  "success": true,
  "data": { "id": 123, "date": "...", "description": "...", "category": "...", "amount": 12.45, "remark": null, "createdAt": "...", "updatedAt": "..." }
}
```

`400`：驗證失敗；`404`：entry 不存在。

### 範例

```bash
curl -X PUT "https://vibeocr.com/api/entries/123" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2024-01-15T12:00:00.000Z",
    "description": "Updated Merchant",
    "category": "Meals & Entertainment",
    "amount": 15.00
  }'
```

---

## DELETE /api/entries/[id]

刪除單筆 entry。

### Response `200`

```json
{
  "success": true,
  "message": "Entry deleted successfully"
}
```

`404`：entry 不存在或不屬於該用戶。

### 範例

```bash
curl -X DELETE "https://vibeocr.com/api/entries/123" \
  -H "Authorization: Bearer $API_KEY"
```

---

## 推薦流程

```mermaid
sequenceDiagram
  participant App
  participant API as VibeOCR API

  App->>API: POST /api/upload (receipt)
  API-->>App: entry.id, editLink?
  App->>API: GET /api/entries
  API-->>App: list / CSV
  App->>API: PUT or DELETE /api/entries/[id]
  API-->>App: updated / deleted
```

---

## 不支援 API Key 的 API（請勿寫入本 skill）

以下需 JWT Cookie 或其它方式，**不能**用 `vibe_pk_`：

- `POST /api/llm-extract`（只提取、不存檔）
- `/api/api-keys`、`/api/history`、`/api/profile`、`/api/settings`、`/api/categories`
- `/api/auth/*`

---

## 實作參考

| 端點 | 程式碼 |
|------|--------|
| 驗證 | `lib/auth.ts` → `getAuthFromApiKey`, `getAuthFlexible` |
| Upload | `app/api/upload/route.ts` |
| Entries | `app/api/entries/route.ts`, `app/api/entries/[id]/route.ts` |

更新後請執行 `npm run skill:build` 同步 https://vibeocr.com/skill.md 。
