์ ์์๋ช ์ ์คํ์ ํตํฉ
๋ดํฌ๋ฅผ ๋ฐ์กํ๊ณ , ์๋ช ์ ์ถ์ ํ๋ฉฐ, ์นํ ์ ์์ ํฉ๋๋ค. ๊ฐ๋จํ REST API, OpenAPI 3.0, curl/Node/Python ์์ โ ๋ช ์๊ฐ ๋ด์ Certyneo๋ฅผ HRIS, CRM ๋๋ ์ ๋ฌด ์ํํธ์จ์ด์ ์ฐ๊ฒฐํ ์ ์๋ ๋ชจ๋ ๊ฒ.
๋น ๋ฅธ ์์
3๋จ๊ณ: ์ค์ ์์ API ํค๋ฅผ ์์ฑํ๊ณ , PDF๋ฅผ base64๋ก ์ธ์ฝ๋ฉํ๋ฉฐ, ๋ฐ์กํฉ๋๋ค. ์๋ต์ ํฌํจ๋ `signUrl`์ ์์ ์์ ์ง์ ๊ณต์ ํ ์ ์์ต๋๋ค.
# 1. Upload the PDF (multipart) and capture the returned document id.
DOC_ID=$(curl -s -X POST https://certyneo.com/api/v1/documents \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "file=@contrat.pdf" | jq -r .id)
# 2. Create a DRAFT envelope referencing the uploaded document.
ENV_ID=$(curl -s -X POST https://certyneo.com/api/v1/envelopes \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d "{
\"subject\": \"Contrat de prestation\",
\"documentIds\": [\"$DOC_ID\"],
\"recipients\": [
{ \"email\": \"client@example.com\", \"name\": \"Marie Dubois\", \"role\": \"SIGNER\" }
]
}" | jq -r .id)
# 3. Dispatch the envelope โ this sends the invitation email/SMS.
curl -X POST https://certyneo.com/api/v1/envelopes/$ENV_ID/send \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"// npm install @certyneo/sdk (or call fetch directly)
const auth = { Authorization: `Bearer ${process.env.CERTYNEO_API_KEY}` };
// 1. Upload the PDF (multipart).
const fd = new FormData();
fd.append("file", new Blob([pdfBuffer], { type: "application/pdf" }), "contrat.pdf");
const doc = await fetch("https://certyneo.com/api/v1/documents", {
method: "POST", headers: auth, body: fd,
}).then((r) => r.json());
// 2. Create the DRAFT envelope.
const envelope = await fetch("https://certyneo.com/api/v1/envelopes", {
method: "POST",
headers: { ...auth, "Content-Type": "application/json" },
body: JSON.stringify({
subject: "Contrat de prestation",
documentIds: [doc.id],
recipients: [
{ email: "client@example.com", name: "Marie Dubois", role: "SIGNER" },
],
}),
}).then((r) => r.json());
// 3. Dispatch โ this triggers the invitation channel for every recipient.
await fetch(`https://certyneo.com/api/v1/envelopes/${envelope.id}/send`, {
method: "POST", headers: auth,
});
console.log(envelope.id);import os, requests
auth = {"Authorization": f"Bearer {os.environ['CERTYNEO_API_KEY']}"}
# 1. Upload the PDF (multipart).
with open("contrat.pdf", "rb") as f:
doc = requests.post(
"https://certyneo.com/api/v1/documents",
headers=auth,
files={"file": ("contrat.pdf", f, "application/pdf")},
).json()
# 2. Create the DRAFT envelope.
envelope = requests.post(
"https://certyneo.com/api/v1/envelopes",
headers={**auth, "Content-Type": "application/json"},
json={
"subject": "Contrat de prestation",
"documentIds": [doc["id"]],
"recipients": [
{"email": "client@example.com", "name": "Marie Dubois", "role": "SIGNER"},
],
},
).json()
# 3. Dispatch โ this triggers the invitation channel for every recipient.
requests.post(
f"https://certyneo.com/api/v1/envelopes/{envelope['id']}/send",
headers=auth,
)
print(envelope["id"])๋ดํฌ
์์ฑ, ๋ฐ์ก, ์ํ ์ถ์ , ์ทจ์. ํ๋์ ๋ดํฌ๋ ์ฌ๋ฌ ๋ฌธ์์ ์ฌ๋ฌ ์๋ช ์(๋ณ๋ ฌ ๋๋ ์์ฐจ)๋ฅผ ํฌํจํ ์ ์์ต๋๋ค.
์นํ
`envelope.created`, `envelope.completed`, `envelope.declined`์ ์ ํํ URL๋ก ์์ ํฉ๋๋ค. ์ถ์ฒ ํ์ธ์ ์ํด ๊ฐ ํ์ด๋ก๋์ HMAC SHA-256์ ์ ์ฉํฉ๋๋ค.
๊ฐ๋จํ ์ธ์ฆ
Bearer ํ ํฐ. ํ๊ฒฝ๋ณ 1๊ฐ ํค(ํ ์คํธ/ํ๋ก๋์ ). ์ฆ์ ์ทจ์ ๊ฐ๋ฅ. ์ด๋น 100 ์์ฒญ/๋ถ/ํค ์ ํ, ์ต๋ 200์ ๋ฒ์คํธ, Retry-After ํค๋๊ฐ ํฌํจ๋ ๊น๋ํ 429 ์๋ต.
์ฌ์ฉ ๊ฐ๋ฅํ ์๋ํฌ์ธํธ
12๊ฐ์ ๊ฒฝ๋ก๋ก ์์ ํ ์ฌ์ดํด ์ปค๋ฒ: envelopes, documents, webhooks, API ํค. ๋ชจ๋ ๊ฒฝ๋ก๋ Bearer ํ ํฐ์ ํ์ฉํ๊ณ JSON์ ๋ฐํํฉ๋๋ค.
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/account/me | Identity of the authenticated caller (id, email, plan) โ scope-less credential probe |
| POST | /api/v1/documents | Upload a PDF (multipart) โ returns document id |
| GET | /api/v1/documents | List documents |
| GET | /api/v1/documents/{id} | Fetch document metadata |
| DELETE | /api/v1/documents/{id} | Delete document |
| GET | /api/v1/envelopes | List envelopes (filter with ?status= and ?limit=) |
| POST | /api/v1/envelopes | Create envelope (status: DRAFT) |
| GET | /api/v1/envelopes/{id} | Fetch envelope state |
| PATCH | /api/v1/envelopes/{id} | Update DRAFT envelope |
| DELETE | /api/v1/envelopes/{id} | Void / delete DRAFT envelope |
| POST | /api/v1/envelopes/{id}/send | Dispatch DRAFT โ sends invitations |
| GET | /api/v1/envelopes/{id}/audit-trail | Download eIDAS audit-trail PDF |
| GET | /api/v1/envelopes/{id}/signed-document | Download signed PDF (once COMPLETED) |
| GET | /api/v1/templates | List reusable envelope templates |
| GET | /api/v1/webhooks | List webhooks |
| POST | /api/v1/webhooks | Register webhook โ returns the signing secret once |
| GET | /api/v1/webhooks/{id} | Fetch webhook subscription |
| PATCH | /api/v1/webhooks/{id} | Update url / events / active state |
| DELETE | /api/v1/webhooks/{id} | Unregister |
| POST | /api/v1/seals | Apply a qualified electronic seal to a document |
| GET | /api/v1/seals/{id} | Fetch seal status |
| GET | /api/v1/seals/{id}/certificate | Download the seal certificate |
| GET | /api/v1/keys | List API keys |
| POST | /api/v1/keys | Create API key โ the secret is shown once |
| PATCH | /api/v1/keys/{id} | Rename / revoke key |
| DELETE | /api/v1/keys/{id} | Delete key |
| GET | /api/v1/billing/usage | Current period usage and projected cost |
| GET | /api/v1/status | Service status |
| GET | /api/v1/openapi | Machine-readable OpenAPI specification |
Authentification
Chaque appel porte une clรฉ API dans l'en-tรชte Authorization. Les clรฉs se gรฉnรจrent depuis Rรฉglages โ Clรฉs API et ne sont affichรฉes qu'une seule fois.
GET /api/v1/account/me HTTP/1.1
Host: certyneo.com
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
# 200 OK
{ "data": { "id": "usr_โฆ", "email": "you@example.com", "plan": "BUSINESS", "environment": "live" } }- โข Format : sk_live_โฆ en production, sk_test_โฆ pour le bac ร sable. En-tรชte : Authorization: Bearer <clรฉ>.
- โข Portรฉes : envelopes, documents, webhooks, seals โ en lecture (:read) ou รฉcriture (:write). L'รฉcriture implique la lecture ; la portรฉe * donne tous les droits.
- โข Les clรฉs sk_test_ crรฉent des ressources en bac ร sable, exclues du quota et de la facturation.
- โข Erreurs : 401 clรฉ invalide, 403 portรฉe insuffisante, 429 limite de dรฉbit dรฉpassรฉe, 402 quota mensuel atteint.
Forme des rรฉponses
Un point ร connaรฎtre avant d'รฉcrire votre client : les collections sont encapsulรฉes dans un objet data, alors que les ressources unitaires sont renvoyรฉes ร plat. Lire response.data.data sur une ressource unitaire renvoie donc undefined.
// GET /api/v1/envelopes
// Collections are WRAPPED in a "data" array.
{
"data": [
{ "id": "env_abc123", "subject": "Contrat", "status": "SENT" }
]
}// GET /api/v1/envelopes/{id}
// Single resources are returned FLAT โ no "data" envelope.
{
"id": "env_abc123",
"subject": "Contrat",
"status": "COMPLETED",
"recipients": [ /* โฆ */ ]
}์์ฒญ ์ ํ
์ ํ์ ๋ชจ๋ ํด๋ผ์ด์ธํธ๋ฅผ ์ํ ์์ ์ ์ธ ์๋น์ค ํ์ง์ ๋ณด์ฅํฉ๋๋ค. ๋ ๋์ ํ๋๊ฐ ํ์ํ์๋ฉด ์ ํฌ์๊ฒ ๋ฌธ์ํ์ธ์.
- โข API ํค๋น ๋ถ๋น 100๊ฐ ์์ฒญ
- โข 10์ด ์ด๋ด์ ์ต๋ 200๊ฐ ์์ฒญ๊น์ง ๋ฒ์คํธ ํ์ฉ
- โข ์ฌ์๋ ์ง์ฐ(์ด)์ ๋ํ๋ด๋ Retry-After ํค๋๊ฐ ํฌํจ๋ 429 ์๋ต
