Get started
Quickstart
Six commands, plain POSIX shell with curl and
python3. The
dashboard's API keys page shows these same
steps with your key filled in, and CI runs them against a live server
before every merge.
Before you start
Your workspace already has a test key. Open Settings, API keys: the keys table shows it shortened, so use its Copy key button (the quickstart on that page also has it filled in). Then type this line in your terminal, with your key in place of the dots:
export SENV_API_KEY=...
It prints nothing. export keeps the key in a shell variable
named SENV_API_KEY for as long as this terminal window is
open, and every command below reads it as $SENV_API_KEY.
In a new window, run the line again.
Keys come in two modes. A senv_test_ key is the right one for
a first run: it is never counted or billed, and the sealed PDF carries a
watermark. Mail to your own workspace's members is delivered, marked as
a test, so you can sign it from your inbox; everyone else's is captured
in the dashboard instead of sent. A senv_live_ key sends
real email, and each envelope is billed when everyone has signed it. The
mode is part of the key, not a request flag.
-
Grab the sample document
curl -s --fail-with-body https://app-staging.signenvoy.com/static/sample-agreement.pdf -o sample.pdf -
Create an envelope with the PDF
DOC=$(curl -s --fail-with-body -X POST https://app-staging.signenvoy.com/v1/documents \ -H "Authorization: Bearer $SENV_API_KEY" \ -F 'document={"title": "Quickstart agreement", "recipients": [{"name": "Ada Lovelace", "email": "ada@example.com"}], "fields": [{"type": "signature", "recipient_index": 0, "page": 1, "x": 0.1, "y": 0.8, "w": 0.35, "h": 0.07}]};type=application/json' \ -F file=@sample.pdf \ | python3 -c "import sys, json; d = json.load(sys.stdin); print(d['id']) if 'id' in d else sys.exit('error: ' + str(d.get('title', d)) + ' see ' + str(d.get('docs_url', '')))") -
Send it
curl -s --fail-with-body -X POST https://app-staging.signenvoy.com/v1/documents/$DOC/send -H "Authorization: Bearer $SENV_API_KEY" -H "Content-Type: application/json" -d '{}' -
Sign it: Ada is not a member of your workspace, so a test key captures her mail instead of sending it. Open Settings, Test mode and click Open signing link (if you put your own address in step 2, the link is in your inbox). Then read it back: status is completed
curl -s --fail-with-body https://app-staging.signenvoy.com/v1/documents/$DOC -H "Authorization: Bearer $SENV_API_KEY" -
Download the sealed PDF, a few seconds after signing. If it prints not-ready, sealing has not finished: wait a few seconds and run it again
curl -s --fail-with-body -L -o signed.pdf "https://app-staging.signenvoy.com/v1/documents/$DOC/download?variant=signed" -H "Authorization: Bearer $SENV_API_KEY" \ || { cat signed.pdf >&2; echo >&2; rm -f signed.pdf; false; } -
Next time, get told instead of checking: add a webhook endpoint (set WEBHOOK_URL to your https URL; the secret is shown once)
curl -s --fail-with-body -X POST https://app-staging.signenvoy.com/v1/webhooks \ -H "Authorization: Bearer $SENV_API_KEY" -H "Content-Type: application/json" \ -d "{\"url\": \"${WEBHOOK_URL:?set WEBHOOK_URL to your https endpoint}\", \"events\": [\"document.completed\", \"document.sealed\"]}"
What happened
Step 2 created a draft in one call: the document's JSON and the PDF
travel together as a multipart/form-data request
(-F), a document part and a file
part, and the answer is the draft with its id. That call checks the PDF
(not empty, a readable PDF, no password, at least one page, at most
50 MB) and every field against it: its page must exist and
its rectangle must stay inside the page (x + w and
y + h at most 1), or it answers 422
validation-failed naming the problem, and nothing is
created. Step 3 sent it: the recipient receives a signing link (or, with
a test key, the email lands under Settings, Test mode). Sign it, then
run step 4: one read, straight after, shows status as
completed. Once sealing finishes, a few seconds later, step 5
downloads the sealed copy with its Certificate of Completion as the last
page. Each value the signer entered (signature, initials, date, text,
checkbox) is stamped into that copy at its field. Before sealing
finishes, the download answers
not-ready.
Get told instead of checking
Step 4 is how you look. In your app, don't look on a timer: step 6 adds a
webhook endpoint, and SignEnvoy calls it when an envelope is completed
and again when the sealed PDF is ready. Set WEBHOOK_URL to an
https URL your server answers; the response carries the signing secret,
shown once. On localhost,
senv webhook tail --forward http://localhost:3000/webhooks/signenvoy --secret YOUR_LOCAL_SECRET
delivers the same events without a tunnel.
Polling and webhooks covers the rules if
you have to poll: every 30 seconds, ETag and
If-None-Match, or ?wait=30.