Captioning API · v1

Picute 캡션 API

비디오 URL을 제출하면 자막이 입혀진 MP4와 서명된 SRT, 트랜스크립트 JSON을 돌려받습니다. v1 전체 사양은 아래에서 확인하세요 — 빠른 시작, 인터랙티브 참조, 웹훅 검증까지.

빠른 시작

선호하는 언어를 선택하세요. 아래 코드는 API 키로 캡션 잡을 제출합니다 — 실행 전에 자리표시자를 본인 키로 바꾸세요.

curl -X POST https://picute.net/api/v1/captions \
  -H "Authorization: Bearer pk_live_<your_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "video_url": "https://cdn.example.com/clip.mp4",
    "language": "auto",
    "preset": "default",
    "callback_url": "https://api.your-app.com/webhooks/picute"
  }'

API 참조

v1의 모든 엔드포인트와 요청 스키마, 에러 코드입니다. 작업을 클릭하면 요청/응답 스키마가 펼쳐집니다.

웹훅

캡션 잡이 종료 상태에 도달하면 Picute가 콜백 URL로 서명된 웹훅을 POST합니다. 페이로드를 신뢰하기 전에 X-Picute-Signature 헤더를 반드시 검증하세요.

이벤트

  • caption.completed캡션 잡 성공. data는 출력 URL이 채워진 Caption 리소스 전체입니다.
  • caption.failed캡션 잡 실패. data.error에 에러 코드와 메시지가 있습니다.

서명 검증

웹훅 시크릿으로 raw 'timestamp.body' 문자열에 대한 HMAC-SHA256을 계산하고, X-Picute-Signature 헤더의 v1= 필드에 들어 있는 hex 다이제스트와 상수 시간 비교하세요.

import hmac, hashlib, time
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = "<your_webhook_secret_from_dashboard>"
TOLERANCE_SECONDS = 5 * 60

def verify(req):
    header = req.headers.get("X-Picute-Signature", "")
    parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p)
    timestamp = int(parts.get("t", "0"))
    received = parts.get("v1", "")
    if abs(time.time() - timestamp) > TOLERANCE_SECONDS:
        return False
    signed = f"{timestamp}.{req.get_data(as_text=True)}".encode("utf-8")
    expected = hmac.new(SECRET.encode("utf-8"), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, received)

@app.post("/webhooks/picute")
def hook():
    if not verify(request):
        abort(401)
    payload = request.get_json()
    print(payload["event"], payload["data"]["id"])
    return "", 204