Integrate e-signatures into your application with the GoSignHere REST API.
https://api.gosignhere.com/v1
All API requests are made to the following base URL. Every endpoint is prefixed with /v1.
All requests must use HTTPS. HTTP requests will be rejected.
All timestamps are ISO 8601, UTC (e.g., 2026-02-20T15:35:00Z).
| Prefix | Resource |
|---|---|
acc_ | Account |
doc_ | Document |
pkg_ | Package |
sgn_ | Signer |
wh_ | Webhook |
cert_ | Certificate |
https://api.gosignhere.com/v1
All API requests require an API key passed via the X-API-Key header. Keys start with gsh_ and are scoped to your account.
API keys are created in your account dashboard under Settings → API Keys, or via the Account API. The full key is shown once at creation — it cannot be retrieved again.
Never send your API key in the query string or request body.
Developer API access is available on Business and Pro plans.
Your key is only used client-side to fill in code examples. It is never sent anywhere.
curl https://api.gosignhere.com/v1/account \ -H "X-API-Key: YOUR_API_KEY"
Every response uses the same JSON envelope. The success field indicates whether the request succeeded. On success, the result is in the result field. On failure, a human-readable message is in the error field.
{
"success": true,
"result": {
"uuid": "pkg_a1b2c3d4e5f6...",
"title": "Service Agreement",
"status": "assigned"
}
}
{
"success": false,
"error": "Document not found",
"code": "not_found",
"status": 404
}
The API uses standard HTTP status codes. Errors include a machine-readable code field for programmatic handling.
| Code | Meaning |
|---|---|
200 | Success |
201 | Created (new resource) |
202 | Accepted (async operation) |
400 | Bad request — missing or invalid parameters |
401 | Unauthorized — invalid or missing API key |
403 | Forbidden — valid key but insufficient permissions |
404 | Not found |
422 | Business rule violation |
429 | Rate limit exceeded |
500 | Internal server error |
| Code | Status | Meaning |
|---|---|---|
unauthorized | 401 | Missing or invalid API key |
forbidden | 403 | Wrong plan or scope |
not_found | 404 | Resource doesn't exist |
validation_error | 422 | Invalid input |
rate_limited | 429 | Too many requests |
insufficient_balance | 422 | Not enough packages |
package_not_assignable | 422 | Can't assign (no fields, no signers, wrong status) |
document_not_ready | 422 | Document still processing |
plan_required | 403 | Feature requires a higher plan |
server_error | 500 | Internal error |
{
"success": false,
"error": "Invalid or missing API key",
"code": "unauthorized",
"status": 401
}
{
"success": false,
"error": "Cannot void a completed package",
"code": "validation_error",
"status": 422
}
{
"success": false,
"error": "Rate limit exceeded. Retry in 23 seconds.",
"code": "rate_limited",
"status": 429
}
API requests are rate-limited per API key. Limits vary by plan.
| Plan | Requests/min | Upload | Create | Bulk |
|---|---|---|---|---|
| Business | 100/min | 20/min | 30/min | 5/min |
| Pro | 200/min | 40/min | 60/min | 10/min |
Every response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per window |
X-RateLimit-Remaining | Requests remaining |
X-RateLimit-Reset | Unix timestamp when window resets |
When rate limited, the response includes a Retry-After header with the number of seconds to wait.
HTTP/1.1 200 OK X-RateLimit-Limit: 100 X-RateLimit-Remaining: 87 X-RateLimit-Reset: 1709251200
HTTP/1.1 429 Too Many Requests
Retry-After: 23
{
"success": false,
"error": "Rate limit exceeded. Retry in 23 seconds.",
"code": "rate_limited",
"status": 429
}
List endpoints support pagination via query parameters.
| Parameter | Default | Max | Description |
|---|---|---|---|
page | 1 | — | Page number |
limit | 25 | 100 | Items per page |
Every list response includes a pagination object with total count and page info.
{
"success": true,
"result": {
"documents": [...],
"pagination": {
"page": 1,
"limit": 25,
"total": 142,
"pages": 6
}
}
}
Get a document signed in two API calls.
Upload a PDF (or DOCX, PNG, etc.) with field placements. If you've already set up a template in the portal with fields placed, skip to step 2 and use from-template instead.
Create a package with your document and signer details. Set auto_assign to true to assign it immediately — signers get an email with a signing link right away.
That's it. Two calls. Your signer gets an email, signs from any device (no account needed), and you get a webhook when it's done.
curl -X POST https://api.gosignhere.com/v1/documents \ -H "X-API-Key: YOUR_API_KEY" \ -F "file=@agreement.pdf"
curl -X POST https://api.gosignhere.com/v1/packages \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Service Agreement",
"auto_assign": true,
"documents": [{
"document_uuid": "doc_abc123...",
"signers": [
{ "role": 1, "name": "Jane Smith", "email": "jane@example.com" }
]
}]
}'
{
"success": true,
"result": {
"uuid": "pkg_xyz789...",
"title": "Service Agreement",
"status": "assigned",
"signers": [
{
"uuid": "sgn_abc...",
"name": "Jane Smith",
"email": "jane@example.com",
"status": "notified",
"signing_url": "https://signing.gosignhere.com/sign/abc123..."
}
]
}
}
Upload a new document. The file is validated by magic bytes (not extension). Non-PDF files are automatically converted to PDF.
| Parameter | Type | Description |
|---|---|---|
file | file | Required. The document file. |
fields | JSON string | Optional. Array of field placements to set on upload. |
Accepted types: PDF, DOCX, PNG, JPG, GIF, TIFF, BMP, RTF, TXT, HTML
PDF files are ready immediately (prep_status: ready). Other formats return prep_status: pending and are converted asynchronously.
| Field | Type | Description |
|---|---|---|
uuid | string | Document ID (prefixed doc_) |
name | string | Original filename |
mime_type | string | Detected MIME type |
prep_status | string | ready, pending, processing, or failed |
page_count | integer | Number of pages |
signer_role_count | integer | Number of distinct signer roles with fields |
curl -X POST https://api.gosignhere.com/v1/documents \ -H "X-API-Key: YOUR_API_KEY" \ -F "file=@agreement.pdf"
{
"success": true,
"result": {
"uuid": "doc_a1b2c3d4e5f6...",
"name": "agreement.pdf",
"mime_type": "application/pdf",
"prep_status": "ready",
"page_count": 3,
"signer_role_count": 0,
"status": "draft",
"is_template": false,
"created_at": "2026-02-20T15:35:00Z"
}
}
List your documents, newest first.
| Parameter | Type | Description |
|---|---|---|
status | string | Filter: draft, ready, archived |
prep_status | string | Filter: pending, processing, ready, failed |
page | integer | Page number (default: 1) |
limit | integer | Per page (default: 25, max: 100) |
curl https://api.gosignhere.com/v1/documents?status=ready&limit=10 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"documents": [
{
"uuid": "doc_a1b2c3d4e5f6...",
"name": "agreement.pdf",
"mime_type": "application/pdf",
"page_count": 3,
"signer_role_count": 2,
"status": "ready",
"is_template": false,
"prep_status": "ready",
"created_at": "2026-02-20T15:35:00Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 12,
"pages": 2
}
}
}
Get document details including field placements.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Document UUID (e.g., doc_a1b2...) |
Includes a fields array with all field placements. Positions are stored as percentages of page dimensions for resolution independence.
curl https://api.gosignhere.com/v1/documents/doc_a1b2c3d4e5f6 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"uuid": "doc_a1b2c3d4e5f6...",
"name": "agreement.pdf",
"mime_type": "application/pdf",
"page_count": 3,
"signer_role_count": 2,
"status": "ready",
"is_template": false,
"prep_status": "ready",
"created_at": "2026-02-20T15:35:00Z",
"fields": [
{
"signer_role": 1,
"type": "signature",
"page": 1,
"x_pct": "15.5000",
"y_pct": "72.3000",
"w_pct": "25.0000",
"h_pct": "5.0000"
}
]
}
}
Download the original uploaded file. Returns the binary file content with the appropriate content type header.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Document UUID |
Binary file with original content type (e.g., application/pdf).
curl https://api.gosignhere.com/v1/documents/doc_a1b2c3d4e5f6/download \ -H "X-API-Key: YOUR_API_KEY" \ -o agreement.pdf
Delete a document. Cannot delete a document that is part of an active package (assigned or in progress).
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Document UUID |
curl -X DELETE https://api.gosignhere.com/v1/documents/doc_a1b2c3d4e5f6 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"deleted": true
}
}
Create a new package with documents, signers, and optional field pre-fills. This is the workhorse endpoint — create, map signers, and optionally assign in one call.
| Parameter | Type | Description |
|---|---|---|
title | string | Required. Package title. |
message | string | Message included in signer notification emails. |
documents | array | Required. Array of document objects (see below). |
auto_assign | boolean | If true, assign immediately and notify signers. Default: false. |
signing_order | string | parallel (default) or sequential. |
expires_in_days | integer | Days until expiration (default: 14). |
fields | object | Map of key_name → value for pre-filling fields. |
metadata | object | Arbitrary key-value pairs stored with the package. |
| Parameter | Type | Description |
|---|---|---|
document_uuid | string | Required. UUID of an uploaded document. |
signers | array | Required. Maps real people to signer roles. |
| Parameter | Type | Description |
|---|---|---|
role | integer | Required. Signer role number (1, 2, 3...). |
name | string | Required. Signer's full name. |
email | string | Required. Signer's email address. |
curl -X POST https://api.gosignhere.com/v1/packages \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Service Agreement — Acme Corp",
"message": "Please review and sign this agreement.",
"signing_order": "sequential",
"expires_in_days": 14,
"auto_assign": true,
"documents": [
{
"document_uuid": "doc_abc123...",
"signers": [
{ "role": 1, "name": "Jane Smith", "email": "jane@acme.com" },
{ "role": 2, "name": "John Doe", "email": "john@acme.com" }
]
}
],
"fields": {
"company_name": "Acme Corp"
}
}'
{
"success": true,
"result": {
"uuid": "pkg_xyz789...",
"title": "Service Agreement — Acme Corp",
"status": "assigned",
"signing_order": "sequential",
"expires_at": "2026-03-15T00:00:00Z",
"documents": [
{
"uuid": "doc_copy_123...",
"name": "Service Agreement.pdf"
}
],
"signers": [
{
"uuid": "sgn_abc...",
"role": 1,
"name": "Jane Smith",
"email": "jane@acme.com",
"status": "notified",
"signing_url": "https://signing.gosignhere.com/sign/abc123..."
},
{
"uuid": "sgn_def...",
"role": 2,
"name": "John Doe",
"email": "john@acme.com",
"status": "pending"
}
],
"created_at": "2026-03-01T00:00:00Z"
}
}
One-call shortcut: copies a template document, creates a package, maps signers, pre-fills fields, and optionally assigns — all in one request. This is what most API integrations use.
| Parameter | Type | Description |
|---|---|---|
template_uuid | string | Required. UUID of a template document. |
title | string | Required. Package title. |
signers | array | Required. Array of signer objects with role, name, email. |
fields | object | Map of key_name → value for pre-filling. |
auto_assign | boolean | Default: true. |
expires_in_days | integer | Days until expiration. |
message | string | Message for signer emails. |
curl -X POST https://api.gosignhere.com/v1/packages/from-template \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_uuid": "doc_abc123...",
"title": "NDA — Jane Smith",
"signers": [
{ "role": 1, "name": "Jane Smith", "email": "jane@acme.com" }
],
"fields": {
"company_name": "Acme Corp",
"start_date": "2026-03-01"
},
"auto_assign": true,
"expires_in_days": 7
}'
{
"success": true,
"result": {
"uuid": "pkg_xyz789...",
"title": "NDA — Jane Smith",
"status": "assigned",
"signers": [
{
"uuid": "sgn_abc...",
"role": 1,
"name": "Jane Smith",
"email": "jane@acme.com",
"status": "notified",
"signing_url": "https://signing.gosignhere.com/sign/abc123..."
}
]
}
}
Simplified all-in-one endpoint: upload a document, create a package, and assign it in a single multipart request. Ideal for simple one-document, one-or-two-signer flows.
| Parameter | Type | Description |
|---|---|---|
file | file | Required. The document file. |
title | string | Required. Package title. |
signers | JSON string | Required. Array of signer objects. |
message | string | Message for signer emails. |
expires_in_days | integer | Days until expiration. |
curl -X POST https://api.gosignhere.com/v1/packages/send \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@contract.pdf" \
-F "title=Freelance Agreement" \
-F 'signers=[{"role":1,"name":"Jane Smith","email":"jane@example.com"}]'
{
"success": true,
"result": {
"uuid": "pkg_xyz789...",
"title": "Freelance Agreement",
"status": "assigned",
"signers": [
{
"uuid": "sgn_abc...",
"name": "Jane Smith",
"email": "jane@example.com",
"status": "notified",
"signing_url": "https://signing.gosignhere.com/sign/abc123..."
}
]
}
}
List your packages, newest first.
| Parameter | Type | Description |
|---|---|---|
status | string | Filter: draft, assigned, in_progress, completed, declined, voided, expired |
page | integer | Page number (default: 1) |
limit | integer | Per page (default: 25, max: 100) |
curl https://api.gosignhere.com/v1/packages?status=completed \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"packages": [
{
"uuid": "pkg_a1b2c3d4...",
"title": "Service Agreement",
"status": "completed",
"document_count": 1,
"created_at": "2026-02-18T10:00:00Z",
"assigned_at": "2026-02-18T10:00:00Z",
"completed_at": "2026-02-19T14:22:00Z",
"expires_at": "2026-03-04T10:00:00Z"
}
],
"pagination": {
"page": 1, "limit": 25, "total": 1, "pages": 1
}
}
}
Get full package details including documents and signers with their current statuses and signing URLs.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Package UUID. |
curl https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"uuid": "pkg_a1b2c3d4e5f6...",
"title": "Service Agreement",
"message": "Please review and sign",
"status": "assigned",
"created_at": "2026-02-18T10:00:00Z",
"assigned_at": "2026-02-18T10:00:00Z",
"expires_at": "2026-03-04T10:00:00Z",
"documents": [
{
"document_uuid": "doc_1a2b3c4d...",
"name": "agreement.pdf",
"status": "pending",
"sort_order": 0
}
],
"signers": [
{
"uuid": "sgn_f6e5d4c3...",
"document_uuid": "doc_1a2b3c4d...",
"signer_role": 1,
"name": "Jane Smith",
"email": "jane@example.com",
"status": "notified",
"signing_url": "https://signing.gosignhere.com/sign/abc123...",
"viewed_at": null,
"signed_at": null
}
]
}
}
Void an active package. Signing links become invalid. Cannot void completed, already voided, or expired packages.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Package UUID. |
curl -X POST https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/void \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"uuid": "pkg_a1b2c3d4e5f6...",
"status": "voided"
}
}
Resend notification emails to all signers who haven't signed yet. The package must be in assigned or in_progress status.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Package UUID. |
curl -X POST https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/resend \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"resent_to": 2
}
}
Resend the notification email to a specific signer. The signer must not have already signed.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Package UUID. |
signer_uuid | string | Required. Signer UUID. |
curl -X POST https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/resend/sgn_f6e5d4c3 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"resent_to": "sgn_f6e5d4c3..."
}
}
Get the audit trail for a package. Returns all events (created, assigned, viewed, signed, etc.) in chronological order.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Package UUID. |
curl https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/events \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"events": [
{
"event": "package.created",
"timestamp": "2026-02-18T10:00:00Z",
"actor": "api_key"
},
{
"event": "package.assigned",
"timestamp": "2026-02-18T10:00:01Z",
"actor": "api_key"
},
{
"event": "signer.viewed",
"timestamp": "2026-02-18T11:30:00Z",
"signer_email": "jane@example.com",
"ip_address": "203.0.113.42"
},
{
"event": "signer.signed",
"timestamp": "2026-02-18T11:35:00Z",
"signer_email": "jane@example.com"
}
]
}
}
Download a signed document from a completed package. Returns the PDF with signature overlays applied.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Package UUID. |
doc_uuid | string | Required. Document UUID within the package. |
Binary PDF with Content-Type: application/pdf.
curl https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4/documents/doc_1a2b3c4d/download \ -H "X-API-Key: YOUR_API_KEY" \ -o signed-agreement.pdf
Generate a Certificate of Completion for a completed package. The certificate includes document hashes, signer details, timestamps, and IP addresses.
The package must be in completed status. If a certificate already exists, it is returned without generating a new one.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Package UUID. |
curl -X POST https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/certificates \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"uuid": "cert_x1y2z3...",
"package_uuid": "pkg_a1b2c3d4e5f6...",
"hash": "sha256:abc123def456...",
"created_at": "2026-02-20T15:40:00Z"
}
}
Download a Certificate of Completion PDF.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Certificate UUID (prefixed cert_). |
Binary PDF with Content-Type: application/pdf.
curl https://api.gosignhere.com/v1/certificates/cert_x1y2z3 \ -H "X-API-Key: YOUR_API_KEY" \ -o certificate.pdf
List your account-level webhooks.
curl https://api.gosignhere.com/v1/webhooks \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"webhooks": [
{
"uuid": "wh_a1b2c3...",
"url": "https://yourapp.com/hooks/gosignhere",
"events": ["package.completed", "package.declined"],
"auth_type": "hmac_sha256",
"active": true,
"created_at": "2026-02-20T15:00:00Z"
}
]
}
}
Register an account-level webhook endpoint.
| Parameter | Type | Description |
|---|---|---|
url | string | Required. HTTPS endpoint URL. |
events | array | Required. Event types to subscribe to. |
auth_type | string | hmac_sha256 (recommended), bearer_token, or basic_auth. |
auth_config | object | Auth credentials (see examples). |
| Type | Config |
|---|---|
hmac_sha256 | { "secret": "your_secret" } |
bearer_token | { "token": "your_token" } |
basic_auth | { "username": "user", "password": "pass" } |
curl -X POST https://api.gosignhere.com/v1/webhooks \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/hooks/gosignhere",
"events": ["package.completed", "package.declined"],
"auth_type": "hmac_sha256",
"auth_config": { "secret": "whsec_your_secret_here" }
}'
{
"success": true,
"result": {
"uuid": "wh_a1b2c3...",
"url": "https://yourapp.com/hooks/gosignhere",
"events": ["package.completed", "package.declined"],
"auth_type": "hmac_sha256",
"active": true,
"created_at": "2026-02-20T15:00:00Z"
}
}
Get webhook details.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Webhook UUID. |
curl https://api.gosignhere.com/v1/webhooks/wh_a1b2c3 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"uuid": "wh_a1b2c3...",
"url": "https://yourapp.com/hooks/gosignhere",
"events": ["package.completed", "package.declined"],
"auth_type": "hmac_sha256",
"active": true,
"created_at": "2026-02-20T15:00:00Z"
}
}
Update a webhook's URL, events, auth, or active status.
| Parameter | Type | Description |
|---|---|---|
url | string | New endpoint URL. |
events | array | Updated event types. |
auth_type | string | Updated auth type. |
auth_config | object | Updated auth credentials. |
active | boolean | Enable or disable the webhook. |
curl -X PUT https://api.gosignhere.com/v1/webhooks/wh_a1b2c3 \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": ["package.completed", "package.declined", "signer.signed"],
"active": true
}'
{
"success": true,
"result": {
"uuid": "wh_a1b2c3...",
"url": "https://yourapp.com/hooks/gosignhere",
"events": ["package.completed", "package.declined", "signer.signed"],
"active": true
}
}
Delete a webhook. Stops all future deliveries.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Webhook UUID. |
curl -X DELETE https://api.gosignhere.com/v1/webhooks/wh_a1b2c3 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"deleted": true
}
}
View the delivery log for a webhook. Shows every attempt (success and failure) with HTTP status, response time, and error messages.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Webhook UUID. |
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
limit | integer | Per page (default: 25, max: 100) |
curl https://api.gosignhere.com/v1/webhooks/wh_a1b2c3/deliveries \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"deliveries": [
{
"event": "package.completed",
"status_code": 200,
"response_time_ms": 245,
"attempt": 1,
"success": true,
"delivered_at": "2026-02-20T15:35:01Z"
},
{
"event": "package.assigned",
"status_code": 500,
"response_time_ms": 1023,
"attempt": 1,
"success": false,
"error": "Internal Server Error",
"delivered_at": "2026-02-20T15:00:01Z"
}
],
"pagination": {
"page": 1, "limit": 25, "total": 2, "pages": 1
}
}
}
Send a test event to a webhook endpoint. The test payload uses a test.ping event so you can verify your endpoint is working.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. Webhook UUID. |
curl -X POST https://api.gosignhere.com/v1/webhooks/wh_a1b2c3/test \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"test_sent": true,
"status_code": 200,
"response_time_ms": 142
}
}
Bulk send packages from a template. Provide a template and an array of recipients — each recipient gets their own package. Returns 202 Accepted with a bulk_id to poll progress.
| Parameter | Type | Description |
|---|---|---|
template_uuid | string | Required. Template document UUID. |
recipients | array | Required. Array of recipient objects. |
title_template | string | Title pattern, e.g. NDA — {{name}}. |
message | string | Message for signer emails. |
expires_in_days | integer | Days until expiration. |
| Parameter | Type | Description |
|---|---|---|
signers | array | Required. Signer objects with role, name, email. |
fields | object | Per-recipient field pre-fills. |
curl -X POST https://api.gosignhere.com/v1/packages/bulk \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_uuid": "doc_abc123...",
"title_template": "NDA — {{name}}",
"expires_in_days": 7,
"recipients": [
{
"signers": [{ "role": 1, "name": "Jane Smith", "email": "jane@example.com" }],
"fields": { "company": "Acme Corp" }
},
{
"signers": [{ "role": 1, "name": "John Doe", "email": "john@example.com" }],
"fields": { "company": "Beta Inc" }
}
]
}'
{
"success": true,
"result": {
"bulk_id": "bulk_x1y2z3...",
"total": 2,
"status": "processing"
}
}
List your bulk send jobs.
curl https://api.gosignhere.com/v1/bulk \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"jobs": [
{
"bulk_id": "bulk_x1y2z3...",
"total": 50,
"completed": 48,
"failed": 2,
"status": "completed",
"created_at": "2026-02-20T15:00:00Z"
}
]
}
}
Poll the progress of a bulk send job. Use this to check how many packages have been created.
| Parameter | Type | Description |
|---|---|---|
bulk_id | string | Required. Bulk job ID. |
curl https://api.gosignhere.com/v1/bulk/bulk_x1y2z3 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"bulk_id": "bulk_x1y2z3...",
"total": 50,
"completed": 35,
"failed": 1,
"status": "processing",
"packages": [
{
"uuid": "pkg_abc...",
"title": "NDA — Jane Smith",
"status": "assigned"
}
],
"created_at": "2026-02-20T15:00:00Z"
}
}
Cancel a running bulk send job. Packages already created are not affected — only remaining unprocessed recipients are skipped.
| Parameter | Type | Description |
|---|---|---|
bulk_id | string | Required. Bulk job ID. |
curl -X POST https://api.gosignhere.com/v1/bulk/bulk_x1y2z3/cancel \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"bulk_id": "bulk_x1y2z3...",
"status": "cancelled",
"completed": 35,
"skipped": 14
}
}
Get your account details including plan, usage, and remaining package balance.
curl https://api.gosignhere.com/v1/account \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"uuid": "acc_a1b2c3d4...",
"name": "Acme Corp",
"plan": "business",
"monthly_limit": 75,
"monthly_used": 12,
"topup_balance": 50,
"package_balance": 113
}
}
List your developer API keys. For security, only the key prefix (first 12 characters) is returned.
curl https://api.gosignhere.com/v1/account/api-keys \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"api_keys": [
{
"uuid": "key_a1b2c3...",
"prefix": "gsh_a1b2c3d4",
"label": "Production",
"created_at": "2026-02-01T00:00:00Z",
"last_used_at": "2026-02-20T15:35:00Z"
}
]
}
}
Create a new developer API key. The full key is returned only once in this response — store it securely.
| Parameter | Type | Description |
|---|---|---|
label | string | A label for this key (e.g., "Production", "Staging"). |
curl -X POST https://api.gosignhere.com/v1/account/api-keys \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "label": "Production" }'
{
"success": true,
"result": {
"uuid": "key_x1y2z3...",
"key": "gsh_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2",
"label": "Production",
"created_at": "2026-02-20T16:00:00Z"
}
}
Revoke an API key. The key immediately stops working. You cannot revoke the key you're currently using to make this request.
| Parameter | Type | Description |
|---|---|---|
uuid | string | Required. API key UUID. |
curl -X DELETE https://api.gosignhere.com/v1/account/api-keys/key_x1y2z3 \ -H "X-API-Key: YOUR_API_KEY"
{
"success": true,
"result": {
"deleted": true
}
}
Public endpoint — no authentication required.
Verify a document or certificate hash against GoSignHere records. Use this to confirm the authenticity and integrity of a signed document.
| Parameter | Type | Description |
|---|---|---|
hash | string | Required. The SHA-256 hash to verify (prefixed with sha256:). |
curl -X POST https://api.gosignhere.com/v1/verify \
-H "Content-Type: application/json" \
-d '{ "hash": "sha256:abc123def456..." }'
{
"success": true,
"result": {
"verified": true,
"certificate_uuid": "cert_x1y2z3...",
"package_uuid": "pkg_a1b2c3d4e5f6...",
"title": "Service Agreement",
"completed_at": "2026-02-19T14:22:00Z"
}
}
{
"success": true,
"result": {
"verified": false,
"message": "No matching certificate found"
}
}
GoSignHere dispatches webhook events when significant actions occur. Events follow the {entity}.{action} naming convention.
| Event | When |
|---|---|
package.created | Package created (draft) |
package.assigned | Package assigned for signing |
package.completed | All signers have signed |
package.declined | A signer declined (package → declined) |
package.voided | Package voided by owner |
package.expired | Package reached expiration date |
signer.notified | Signer received invite email |
signer.viewed | Signer opened the signing link |
signer.signed | Individual signer completed signing |
signer.declined | Individual signer declined |
{
"event": "package.completed",
"timestamp": "2026-02-20T15:35:00Z",
"account_uuid": "acc_abc123...",
"data": {
"package": {
"uuid": "pkg_a1b2c3d4e5f6...",
"title": "Service Agreement",
"status": "completed",
"completed_at": "2026-02-20T15:35:00Z"
}
}
}
{
"event": "signer.signed",
"timestamp": "2026-03-01T15:30:00Z",
"account_uuid": "acc_abc123...",
"data": {
"package": {
"uuid": "pkg_xyz789...",
"title": "Service Agreement",
"status": "in_progress"
},
"signer": {
"uuid": "sgn_abc...",
"name": "Jane Smith",
"email": "jane@acme.com",
"role": 1,
"signed_at": "2026-03-01T15:30:00Z"
}
}
}
All webhook payloads share the same structure:
| Field | Type | Description |
|---|---|---|
event | string | Event type (e.g., signer.signed) |
timestamp | string | ISO 8601 UTC timestamp |
account_uuid | string | Your account UUID |
data | object | Event-specific payload data |
Webhooks are delivered as HTTP POST requests with Content-Type: application/json. Your endpoint must respond with a 2xx status code within 10 seconds.
POST /your/webhook/endpoint HTTP/1.1 Content-Type: application/json X-GSH-Signature: sha256=a1b2c3d4e5f6... User-Agent: GoSignHere-Webhook/1.0
When using hmac_sha256 auth, every webhook delivery includes an X-GSH-Signature header. Verify it by computing the HMAC-SHA256 of the raw request body using your webhook secret.
Always compare signatures using a timing-safe comparison function to prevent timing attacks.
# Verify with openssl
BODY='{"event":"package.completed",...}'
SECRET="whsec_your_secret"
EXPECTED=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2)
echo "sha256=$EXPECTED"
# Compare with X-GSH-Signature header
If your endpoint doesn't respond with a 2xx status within 10 seconds, the delivery is considered failed and will be retried with exponential backoff.
| Attempt | Delay | Total Elapsed |
|---|---|---|
| 1 | Immediate | 0 |
| 2 | 1 minute | 1 min |
| 3 | 5 minutes | 6 min |
| 4 | 30 minutes | 36 min |
| 5 | 2 hours | ~2.5 hrs |
| 6 | 8 hours | ~10.5 hrs |
After 6 failed attempts, the event is marked as permanently failed. No more retries.
Automatic disable: If a webhook endpoint fails 50 consecutive deliveries, the webhook is automatically disabled and you'll receive a notification email.
1. Respond quickly
Return 200 immediately, then process
the event asynchronously.
2. Handle duplicates
Events may be delivered more than once.
Use the event timestamp to deduplicate.
3. Verify signatures
Always verify the X-GSH-Signature header
before processing webhook payloads.
4. Monitor deliveries
Use GET /v1/webhooks/{uuid}/deliveries
to check for failed deliveries.