Từ lúc bạn bấm Enter đến lúc nhận bài viết. Chuyện gì xảy ra?
Không cần hiểu code để dùng được. Nhưng nếu bạn tò mò, đây là chỗ của sự thật.
Tại sao 6/10, không 8/10?
Trước khi đi sâu vào từng bước, có 1 câu hỏi bạn sẽ thắc mắc: "Sao chất lượng tối thiểu chỉ 6/10? Nghe thấp vậy?"
Đây là điểm quan trọng nên mình giải thích sớm — không phải con số tự bịa. 6/10 là điểm cân bằng rút ra sau khi test trên hàng ngàn bài viết thực tế:
- Đặt cao hơn (vd 8/10): reviewer khắt khe quá, nhiều bài đáng được giao lại bị reject. Bạn phải retry, mất thời gian, bực mình.
- Đặt thấp hơn (vd 4/10): quá nhiều bài tệ lọt qua, bạn nhận về rồi mất niềm tin vào hệ thống.
- 6/10: vừa đủ. Output ở mức 6+ rất hiếm khi cần reject — bạn thường chỉ tweak nhẹ là đăng được luôn.
Và nó còn kết hợp với điều kiện "AND" — nghĩa là cả 2 phải cùng đúng: verdict = APPROVE VÀ score ≥ 6. Không có chuyện "score 9 nhưng verdict REJECT vẫn được duyệt" — hai điều kiện phải cùng pass.
Cái hay ở đây là: nếu score < 6 hoặc verdict = REJECT → job không tính quota. Bạn không mất gì khi hệ thống reject. Đây là risk reversal cốt lõi của pipeline.
Lấy key
capi_xxx… — không expire, có thể tạo nhiều key để revoke từng cái.Bạn gọi
/playground trong dashboard → điền topic → click Generate. Không cài gì.write_content.POST /v1/content/generate với header x-api-key. Sau dùng GET /v1/content/{job_id} để kiểm tra.Server
kiểm tra
401).pending / running / completed. Bài bị reject hoặc failed không tính → bạn không mất quota vào thất bại.job_id duy nhất → gửi vào queue chờ xử lý → trả 202 + job_id + thời gian dự kiến.Writer
viết
Reviewer
chấm
Auto-
quyết
- Verdict = APPROVE VÀ score ≥ 6/10
- Cả 2 điều kiện phải đúng — đề phòng reviewer "APPROVE" ở score thấp
- → Draft thành content final
- Patches[] khớp được text trong draft
- → Auto-apply patches (tự sửa, bạn không cần duyệt)
- → Giao content đã sửa xong
- Patches không match được text trong draft
- → Vẫn giao content kèm issues[] gợi ý sửa
- → Không phải REJECT — bạn vẫn nhận output dùng được
- Verdict = REJECT, hoặc verdict = APPROVE nhưng score < 6
- → Status =
rejected, không tính quota - → Nhận issues[] → retry với brief tốt hơn
Bạn
nhận
GET /v1/content/{job_id} mỗi 3–5s cho đến khi status = completed. CLI và MCP làm tự động.X-Content-Signature để verify origin. Retry 3 lần exponential backoff tự động.{ content, quality_score, voice_mode, tier, review_report, generated_at }quality_score là snapshot từ lúc generate → audit trail không bị vỡ khi bạn update voice sau này.Giọng được bảo vệ
Voice profile (samples, quy tắc viết) không bao giờ rời server. Không endpoint nào trả raw voice data. Khi bạn update voice, version cũ vẫn audit trail được — không sợ mất vết.
Quality gate độc lập
Writer viết, Reviewer chấm — 2 instance tách riêng với 2 prompt khác nhau. Threshold 6/10 + AND logic = không có chuyện "APPROVE ở score thấp." Auto-patch = sửa mà không cần bạn duyệt.
API mỗi nơi
MCP trên Claude Desktop / Cursor / VS Code. REST trên curl / Postman / script. Playground trên browser. 1 API key, mọi nơi — không cần học 3 cách khác nhau.
Chỉ trả tiền khi dùng được
Quota chỉ tính jobs pending / running / completed. Rejected hay failed? Miễn phí. Bạn chỉ trả tiền cho output có giá trị, không trả cho retry.
Câu hỏi hay gặp
quality_score → đọc review_report. Nếu thích pipeline, lên Starter để mở blog, article, landing.rejected. Bạn nhận review_report.issues chi tiết → biết cần fix gì → retry với brief rõ hơn. Job rejected không tính quota. Lưu ý: 7/10 với verdict APPROVE thì PASS (7 ≥ 6).POST /v1/voices với 1–10 writing samples + hard_rules (vd: no_emoji). Server hash thành voice_version (SHA-1 snapshot). Mỗi lần generate snapshot version → audit trail. Khi update voice, version mới tự bump, old version vẫn lưu được.tier=basic (checklist đơn giản hơn).X-Content-Signature: sha256={hex} — đó là chữ ký của request để bạn verify origin (không phải spam). Không verify cũng được, nhưng nên làm để an toàn hơn.pending, running, completed vào quota. rejected và failed bị skip. Bạn có thể check GET /v1/auth/usage để thấy quota thực tế.Tham chiếu kỹ thuật (cho dev)
POST /v1/content/generate · GET /v1/content/:id · POST/GET/PUT /v1/voiceshttps://content-apiapi-production.up.railway.app/mcp (Streamable HTTP) · 3 tools: write_content, list_voices, get_content_statusx-api-key header hoặc Authorization: Bearer. Key raw chỉ hiện 1 lần khi tạo.deepseek-v4-flash (basic) · deepseek-v4-pro (upgrade · pro). Pro tier set thinking: enabled + reasoning_effort: high.{ name, samples[], hard_rules[], mode_default } → hash thành voice_version SHA-1 (12 hex chars)analysis bất kể tier.verdict === "APPROVE" AND voice_score >= 6. REQUEST_CHANGES auto-patch via replaceAll. REQUEST_CHANGES no-match → ship với advisory. Reviewer fail → REJECT (fail closed).pending · running · completed. Free: rejected · failed.X-Content-Signature: sha256=<hex> = HMAC-SHA256(raw_body, secret). Verify timingSafeEqual.400 validation · 401 auth · 403 tier · 404 not found · 429 quota · 503 queue unavailablevoice_version (snapshot at generation) · quality_score · review_report · tier · voice_mode · generated_at