Quick overview
Authentication is a per-workspace bearer token you issue in settings. A full send is three calls at most: create the envelope with its documents, recipients and field placements, send it, then read state (or wait for the webhook). Nobody has to open our editor for that path.
Base URL
https://vg-sign.com/api/v1The base path used to be /api/v1/internal. That prefix still answers, and will keep answering — nothing built against it needs changing. It was never accurate: every endpoint below takes an ordinary workspace token.
A machine-readable description of everything on this page lives at /api/v1/openapi.json (OpenAPI 3.1). Point a client generator at it, or import it into Postman or Insomnia.
Authentication
Issue a workspace API token in Settings → Integrations, then call the API with Authorization: Bearer vgs_live_…. Tokens are scoped to your workspace, hashed at rest, and revocable at any time.
Signing an agent in from a CRM is a separate, higher privilege. The single-use SSO hand-off at /oauth/authorize, the On-Behalf-Of header and entitlement revocation are only answered for a workspace we have enabled as a CRM service account, and only for people who are already in that workspace. An ordinary workspace token gets 403 not_a_service_account on those three; everything else on this page works with any token. Ask us at info@vg-realestate.ca to have a workspace enabled.
Core endpoints
POST /envelopes: create an envelope from one or more uploaded PDFs (multipart/form-data: ametadataJSON part plus onefilespart per document). Recipients, signing order and — optionally — field placements are all in the same payload. Returns201with the envelope id,status: "draft", andfields_required, which isfalseonce you have placed the fields yourself.POST /envelopes/:id/send: send a draft for signature. Emails the signers, rotates their signing links, and records the send in the audit trail.GET /envelopes: list the workspace’s envelopes, newest first. Filters:status,external_ref; paging:limit(max 100),offset.GET /envelopes/:id: read envelope state, recipient progress and the audit trail.GET /envelopes/:id/final: fetch the signed, flattened PDF(s).GET /envelopes/:id/certificate: fetch the certificate of completion.POST /envelopes/:id/remind: re-send the signing notification to pending recipients.POST /envelopes/:id/void: void an in-flight envelope.POST /envelopes/from-refs: create an envelope from documents already uploaded through/uploads/init, by reference.POST /webhooks·GET /webhooks·DELETE /webhooks/:id: manage lifecycle-event subscriptions.
Recipients
GET /envelopes/:id/recipients returns the people on an envelope and where each of them stands. On a draft, POST /envelopes/:id/recipients adds someone, PATCH /envelopes/:id/recipients/:rid edits them (name, email, phone, label, signer or copy-only, position in the signing order) and DELETE removes them — the delete is refused while that person still owns placed fields, since removing them would take those fields too; pass ?force=true to accept it.
After a send, the same PATCHhandles the mistyped-address case: name and email only, and only for someone who has not yet signed or declined. Changing the email retires the link that went to the wrong address and issues a new one, emailed to the corrected address when it is that person’s turn. The deadline carries over rather than restarting, and the substitution is recorded in the audit trail. POST /envelopes/:id/recipients/:rid/remind nudges one named person, where the envelope-level reminder chases whoever is currently holding things up.
Templates
A template carries the documents, the field layout and the signing roles, so a recurring pack is one call rather than an upload plus a field layout plus a send. GET /templates lists them; GET /templates/:id returns the roles you have to fill; POST /templates/:id/envelopes binds a real person to each role and creates the envelope. Add "send": true to have it go out in the same request.
POST /templates/8f3c…/envelopes
{
"assignments": [
{ "signing_order": 1, "full_name": "Dana Reyes", "email": "dana@example.com" }
],
"external_ref": "deal-4417",
"send": true
}Placing fields
Each entry in fields[] is one box on one page, assigned to one recipient. Coordinates are fractions of the page — 0 to 1, measured from the top-left corner — so they hold for any page size. document names a file from documents[] and can be omitted when the envelope has a single signable document.
{
"recipient_email": "buyer@example.com",
"document": "contract.pdf",
"type": "signature",
"page": 1,
"x": 0.12, "y": 0.60,
"width": 0.30, "height": 0.07,
"required": true
}Types: signature, initials, full_name, text, date, time, checkbox, strikethrough. Text fields also take placeholder, max_length and validation (email · number · phone); dates take date_format, times take time_format and time_mode, checkboxes take checkbox_style. A rejected placement comes back as a 400 naming the entry, e.g. fields[2].page is 9 but "contract.pdf" has 4 page(s).
Skip fields[] and the response carries fields_required: true plus an editor_url: the envelope waits as a draft until somebody places the fields in the VG·Sign editor. Every signer needs at least one required field, or the send is refused.
Webhook events
Every state change emits a webhook with a signed payload. The events an integration usually subscribes to: envelope.created, envelope.sent, envelope.opened, envelope.document_signed, envelope.all_signed, envelope.completed, envelope.declined, envelope.voided, envelope.expired, envelope.recalled, envelope.reminded.
Each delivery carries an X-VG-Signature: sha256=<hex>header, an HMAC-SHA256 of the raw request body, keyed with your subscription’s shared secret. Recompute it and compare before processing.X-VG-Delivery-Id repeats the id in the body — deduplicate on it, since delivery is at-least-once.
SDKs
The API is plain REST + JSON, so any HTTP client works. There is no hand-written client SDK, but /api/v1/openapi.json is a complete OpenAPI 3.1 description, which most generators will turn into a typed client for your language. If you would rather have one we maintain, tell us at info@vg-realestate.ca.
Rate limits
Each workspace token is limited to 600 requests per minute (and 600/min per source IP), measured over a rolling 60-second window. Reminder sends are capped tighter, at 60/min. Over-limit requests get a 429 with a Retry-After header. Need a higher ceiling? Contact us.
Limits
Up to 15 documents per envelope, 25 MB and 50 pages per PDF, 50 recipients and 500 field placements. Uploads to POST /envelopesmust be PDFs; other formats go through the web uploader, which converts them first. Envelope creation counts against your plan’s monthly allowance and answers 402 when it runs out.