API Reference

Integrate e-signatures into your application with the GoSignHere REST API.

https://api.gosignhere.com/v1
Language

Getting Started

Base URL

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).

Resource ID Prefixes

PrefixResource
acc_Account
doc_Document
pkg_Package
sgn_Signer
wh_Webhook
cert_Certificate
Base URL
https://api.gosignhere.com/v1

Authentication

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.

Plans with API Access

Developer API access is available on Business and Pro plans.

Try it — paste your API key

Your key is only used client-side to fill in code examples. It is never sent anywhere.

Request
curl https://api.gosignhere.com/v1/account \
  -H "X-API-Key: YOUR_API_KEY"

Response Format

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 Response
{
  "success": true,
  "result": {
    "uuid": "pkg_a1b2c3d4e5f6...",
    "title": "Service Agreement",
    "status": "assigned"
  }
}
Error Response
{
  "success": false,
  "error": "Document not found",
  "code": "not_found",
  "status": 404
}

Error Handling

The API uses standard HTTP status codes. Errors include a machine-readable code field for programmatic handling.

HTTP Status Codes

CodeMeaning
200Success
201Created (new resource)
202Accepted (async operation)
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing API key
403Forbidden — valid key but insufficient permissions
404Not found
422Business rule violation
429Rate limit exceeded
500Internal server error

Error Codes

CodeStatusMeaning
unauthorized401Missing or invalid API key
forbidden403Wrong plan or scope
not_found404Resource doesn't exist
validation_error422Invalid input
rate_limited429Too many requests
insufficient_balance422Not enough packages
package_not_assignable422Can't assign (no fields, no signers, wrong status)
document_not_ready422Document still processing
plan_required403Feature requires a higher plan
server_error500Internal error
401 Unauthorized
{
  "success": false,
  "error": "Invalid or missing API key",
  "code": "unauthorized",
  "status": 401
}
422 Business Rule Violation
{
  "success": false,
  "error": "Cannot void a completed package",
  "code": "validation_error",
  "status": 422
}
429 Rate Limited
{
  "success": false,
  "error": "Rate limit exceeded. Retry in 23 seconds.",
  "code": "rate_limited",
  "status": 429
}

Rate Limits

API requests are rate-limited per API key. Limits vary by plan.

Limits by Plan

PlanRequests/minUploadCreateBulk
Business100/min20/min30/min5/min
Pro200/min40/min60/min10/min

Response Headers

Every response includes rate limit headers:

HeaderDescription
X-RateLimit-LimitMax requests per window
X-RateLimit-RemainingRequests remaining
X-RateLimit-ResetUnix timestamp when window resets

When rate limited, the response includes a Retry-After header with the number of seconds to wait.

Rate Limit Headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1709251200
429 Too Many Requests
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
}

Quickstart

Get a document signed in two API calls.

Step 1: Upload a Document

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.

Step 2: Create & Assign a Package

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.

Step 1 — Upload Document
curl -X POST https://api.gosignhere.com/v1/documents \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@agreement.pdf"
Step 2 — Create & Assign Package
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" }
      ]
    }]
  }'
Response — 201
{
  "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..."
      }
    ]
  }
}

Documents

POST /v1/documents

Upload a new document. The file is validated by magic bytes (not extension). Non-PDF files are automatically converted to PDF.

Request Body (multipart/form-data)

ParameterTypeDescription
filefileRequired. The document file.
fieldsJSON stringOptional. 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.

Response Fields

FieldTypeDescription
uuidstringDocument ID (prefixed doc_)
namestringOriginal filename
mime_typestringDetected MIME type
prep_statusstringready, pending, processing, or failed
page_countintegerNumber of pages
signer_role_countintegerNumber of distinct signer roles with fields
Request
curl -X POST https://api.gosignhere.com/v1/documents \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@agreement.pdf"
Response — 201
{
  "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"
  }
}

GET /v1/documents

List your documents, newest first.

Query Parameters

ParameterTypeDescription
statusstringFilter: draft, ready, archived
prep_statusstringFilter: pending, processing, ready, failed
pageintegerPage number (default: 1)
limitintegerPer page (default: 25, max: 100)
Request
curl https://api.gosignhere.com/v1/documents?status=ready&limit=10 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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 /v1/documents/{uuid}

Get document details including field placements.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Document UUID (e.g., doc_a1b2...)

Response

Includes a fields array with all field placements. Positions are stored as percentages of page dimensions for resolution independence.

Request
curl https://api.gosignhere.com/v1/documents/doc_a1b2c3d4e5f6 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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"
      }
    ]
  }
}

GET /v1/documents/{uuid}/download

Download the original uploaded file. Returns the binary file content with the appropriate content type header.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Document UUID

Response

Binary file with original content type (e.g., application/pdf).

Request
curl https://api.gosignhere.com/v1/documents/doc_a1b2c3d4e5f6/download \
  -H "X-API-Key: YOUR_API_KEY" \
  -o agreement.pdf

DELETE /v1/documents/{uuid}

Delete a document. Cannot delete a document that is part of an active package (assigned or in progress).

Path Parameters

ParameterTypeDescription
uuidstringRequired. Document UUID
Request
curl -X DELETE https://api.gosignhere.com/v1/documents/doc_a1b2c3d4e5f6 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "deleted": true
  }
}

Packages

POST /v1/packages

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.

Request Body

ParameterTypeDescription
titlestringRequired. Package title.
messagestringMessage included in signer notification emails.
documentsarrayRequired. Array of document objects (see below).
auto_assignbooleanIf true, assign immediately and notify signers. Default: false.
signing_orderstringparallel (default) or sequential.
expires_in_daysintegerDays until expiration (default: 14).
fieldsobjectMap of key_name → value for pre-filling fields.
metadataobjectArbitrary key-value pairs stored with the package.

Document Object

ParameterTypeDescription
document_uuidstringRequired. UUID of an uploaded document.
signersarrayRequired. Maps real people to signer roles.

Signer Object

ParameterTypeDescription
roleintegerRequired. Signer role number (1, 2, 3...).
namestringRequired. Signer's full name.
emailstringRequired. Signer's email address.
Request
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"
    }
  }'
Response — 201
{
  "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"
  }
}

POST /v1/packages/from-template

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.

Request Body

ParameterTypeDescription
template_uuidstringRequired. UUID of a template document.
titlestringRequired. Package title.
signersarrayRequired. Array of signer objects with role, name, email.
fieldsobjectMap of key_name → value for pre-filling.
auto_assignbooleanDefault: true.
expires_in_daysintegerDays until expiration.
messagestringMessage for signer emails.
Request
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
  }'
Response — 201
{
  "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..."
      }
    ]
  }
}

POST /v1/packages/send

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.

Request Body (multipart/form-data)

ParameterTypeDescription
filefileRequired. The document file.
titlestringRequired. Package title.
signersJSON stringRequired. Array of signer objects.
messagestringMessage for signer emails.
expires_in_daysintegerDays until expiration.
Request
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"}]'
Response — 201
{
  "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..."
      }
    ]
  }
}

GET /v1/packages

List your packages, newest first.

Query Parameters

ParameterTypeDescription
statusstringFilter: draft, assigned, in_progress, completed, declined, voided, expired
pageintegerPage number (default: 1)
limitintegerPer page (default: 25, max: 100)
Request
curl https://api.gosignhere.com/v1/packages?status=completed \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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 /v1/packages/{uuid}

Get full package details including documents and signers with their current statuses and signing URLs.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Package UUID.
Request
curl https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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
      }
    ]
  }
}

POST /v1/packages/{uuid}/void

Void an active package. Signing links become invalid. Cannot void completed, already voided, or expired packages.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Package UUID.
Request
curl -X POST https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/void \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "uuid": "pkg_a1b2c3d4e5f6...",
    "status": "voided"
  }
}

POST /v1/packages/{uuid}/resend

Resend notification emails to all signers who haven't signed yet. The package must be in assigned or in_progress status.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Package UUID.
Request
curl -X POST https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/resend \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "resent_to": 2
  }
}

POST /v1/packages/{uuid}/resend/{signer_uuid}

Resend the notification email to a specific signer. The signer must not have already signed.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Package UUID.
signer_uuidstringRequired. Signer UUID.
Request
curl -X POST https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/resend/sgn_f6e5d4c3 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "resent_to": "sgn_f6e5d4c3..."
  }
}

GET /v1/packages/{uuid}/events

Get the audit trail for a package. Returns all events (created, assigned, viewed, signed, etc.) in chronological order.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Package UUID.
Request
curl https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/events \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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"
      }
    ]
  }
}

GET /v1/packages/{uuid}/documents/{doc_uuid}/download

Download a signed document from a completed package. Returns the PDF with signature overlays applied.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Package UUID.
doc_uuidstringRequired. Document UUID within the package.

Response

Binary PDF with Content-Type: application/pdf.

Request
curl https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4/documents/doc_1a2b3c4d/download \
  -H "X-API-Key: YOUR_API_KEY" \
  -o signed-agreement.pdf

Certificates

POST /v1/packages/{uuid}/certificates

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.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Package UUID.
Request
curl -X POST https://api.gosignhere.com/v1/packages/pkg_a1b2c3d4e5f6/certificates \
  -H "X-API-Key: YOUR_API_KEY"
Response — 201
{
  "success": true,
  "result": {
    "uuid": "cert_x1y2z3...",
    "package_uuid": "pkg_a1b2c3d4e5f6...",
    "hash": "sha256:abc123def456...",
    "created_at": "2026-02-20T15:40:00Z"
  }
}

GET /v1/certificates/{uuid}

Download a Certificate of Completion PDF.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Certificate UUID (prefixed cert_).

Response

Binary PDF with Content-Type: application/pdf.

Request
curl https://api.gosignhere.com/v1/certificates/cert_x1y2z3 \
  -H "X-API-Key: YOUR_API_KEY" \
  -o certificate.pdf

Webhooks

GET /v1/webhooks

List your account-level webhooks.

Request
curl https://api.gosignhere.com/v1/webhooks \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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"
      }
    ]
  }
}

POST /v1/webhooks

Register an account-level webhook endpoint.

Request Body

ParameterTypeDescription
urlstringRequired. HTTPS endpoint URL.
eventsarrayRequired. Event types to subscribe to.
auth_typestringhmac_sha256 (recommended), bearer_token, or basic_auth.
auth_configobjectAuth credentials (see examples).

Auth Config by Type

TypeConfig
hmac_sha256{ "secret": "your_secret" }
bearer_token{ "token": "your_token" }
basic_auth{ "username": "user", "password": "pass" }
Request
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" }
  }'
Response — 201
{
  "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 /v1/webhooks/{uuid}

Get webhook details.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Webhook UUID.
Request
curl https://api.gosignhere.com/v1/webhooks/wh_a1b2c3 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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"
  }
}

PUT /v1/webhooks/{uuid}

Update a webhook's URL, events, auth, or active status.

Request Body

ParameterTypeDescription
urlstringNew endpoint URL.
eventsarrayUpdated event types.
auth_typestringUpdated auth type.
auth_configobjectUpdated auth credentials.
activebooleanEnable or disable the webhook.
Request
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
  }'
Response — 200
{
  "success": true,
  "result": {
    "uuid": "wh_a1b2c3...",
    "url": "https://yourapp.com/hooks/gosignhere",
    "events": ["package.completed", "package.declined", "signer.signed"],
    "active": true
  }
}

DELETE /v1/webhooks/{uuid}

Delete a webhook. Stops all future deliveries.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Webhook UUID.
Request
curl -X DELETE https://api.gosignhere.com/v1/webhooks/wh_a1b2c3 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "deleted": true
  }
}

GET /v1/webhooks/{uuid}/deliveries

View the delivery log for a webhook. Shows every attempt (success and failure) with HTTP status, response time, and error messages.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Webhook UUID.

Query Parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
limitintegerPer page (default: 25, max: 100)
Request
curl https://api.gosignhere.com/v1/webhooks/wh_a1b2c3/deliveries \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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
    }
  }
}

POST /v1/webhooks/{uuid}/test

Send a test event to a webhook endpoint. The test payload uses a test.ping event so you can verify your endpoint is working.

Path Parameters

ParameterTypeDescription
uuidstringRequired. Webhook UUID.
Request
curl -X POST https://api.gosignhere.com/v1/webhooks/wh_a1b2c3/test \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "test_sent": true,
    "status_code": 200,
    "response_time_ms": 142
  }
}

Bulk Operations

POST /v1/packages/bulk

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.

Request Body

ParameterTypeDescription
template_uuidstringRequired. Template document UUID.
recipientsarrayRequired. Array of recipient objects.
title_templatestringTitle pattern, e.g. NDA — {{name}}.
messagestringMessage for signer emails.
expires_in_daysintegerDays until expiration.

Recipient Object

ParameterTypeDescription
signersarrayRequired. Signer objects with role, name, email.
fieldsobjectPer-recipient field pre-fills.
Request
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" }
      }
    ]
  }'
Response — 202 Accepted
{
  "success": true,
  "result": {
    "bulk_id": "bulk_x1y2z3...",
    "total": 2,
    "status": "processing"
  }
}

GET /v1/bulk

List your bulk send jobs.

Request
curl https://api.gosignhere.com/v1/bulk \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "jobs": [
      {
        "bulk_id": "bulk_x1y2z3...",
        "total": 50,
        "completed": 48,
        "failed": 2,
        "status": "completed",
        "created_at": "2026-02-20T15:00:00Z"
      }
    ]
  }
}

GET /v1/bulk/{bulk_id}

Poll the progress of a bulk send job. Use this to check how many packages have been created.

Path Parameters

ParameterTypeDescription
bulk_idstringRequired. Bulk job ID.
Request
curl https://api.gosignhere.com/v1/bulk/bulk_x1y2z3 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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"
  }
}

POST /v1/bulk/{bulk_id}/cancel

Cancel a running bulk send job. Packages already created are not affected — only remaining unprocessed recipients are skipped.

Path Parameters

ParameterTypeDescription
bulk_idstringRequired. Bulk job ID.
Request
curl -X POST https://api.gosignhere.com/v1/bulk/bulk_x1y2z3/cancel \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "bulk_id": "bulk_x1y2z3...",
    "status": "cancelled",
    "completed": 35,
    "skipped": 14
  }
}

Account

GET /v1/account

Get your account details including plan, usage, and remaining package balance.

Request
curl https://api.gosignhere.com/v1/account \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "uuid": "acc_a1b2c3d4...",
    "name": "Acme Corp",
    "plan": "business",
    "monthly_limit": 75,
    "monthly_used": 12,
    "topup_balance": 50,
    "package_balance": 113
  }
}

GET /v1/account/api-keys

List your developer API keys. For security, only the key prefix (first 12 characters) is returned.

Request
curl https://api.gosignhere.com/v1/account/api-keys \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "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"
      }
    ]
  }
}

POST /v1/account/api-keys

Create a new developer API key. The full key is returned only once in this response — store it securely.

Request Body

ParameterTypeDescription
labelstringA label for this key (e.g., "Production", "Staging").
Request
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" }'
Response — 201
{
  "success": true,
  "result": {
    "uuid": "key_x1y2z3...",
    "key": "gsh_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2",
    "label": "Production",
    "created_at": "2026-02-20T16:00:00Z"
  }
}

DELETE /v1/account/api-keys/{uuid}

Revoke an API key. The key immediately stops working. You cannot revoke the key you're currently using to make this request.

Path Parameters

ParameterTypeDescription
uuidstringRequired. API key UUID.
Request
curl -X DELETE https://api.gosignhere.com/v1/account/api-keys/key_x1y2z3 \
  -H "X-API-Key: YOUR_API_KEY"
Response — 200
{
  "success": true,
  "result": {
    "deleted": true
  }
}

Verification

POST /v1/verify

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.

Request Body

ParameterTypeDescription
hashstringRequired. The SHA-256 hash to verify (prefixed with sha256:).
Request
curl -X POST https://api.gosignhere.com/v1/verify \
  -H "Content-Type: application/json" \
  -d '{ "hash": "sha256:abc123def456..." }'
Response — Verified
{
  "success": true,
  "result": {
    "verified": true,
    "certificate_uuid": "cert_x1y2z3...",
    "package_uuid": "pkg_a1b2c3d4e5f6...",
    "title": "Service Agreement",
    "completed_at": "2026-02-19T14:22:00Z"
  }
}
Response — Not Found
{
  "success": true,
  "result": {
    "verified": false,
    "message": "No matching certificate found"
  }
}

Webhook Events

Event Types

GoSignHere dispatches webhook events when significant actions occur. Events follow the {entity}.{action} naming convention.

EventWhen
package.createdPackage created (draft)
package.assignedPackage assigned for signing
package.completedAll signers have signed
package.declinedA signer declined (package → declined)
package.voidedPackage voided by owner
package.expiredPackage reached expiration date
signer.notifiedSigner received invite email
signer.viewedSigner opened the signing link
signer.signedIndividual signer completed signing
signer.declinedIndividual signer declined
package.completed payload
{
  "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"
    }
  }
}
signer.signed payload
{
  "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"
    }
  }
}

Payload Format

All webhook payloads share the same structure:

FieldTypeDescription
eventstringEvent type (e.g., signer.signed)
timestampstringISO 8601 UTC timestamp
account_uuidstringYour account UUID
dataobjectEvent-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.

Webhook Headers
POST /your/webhook/endpoint HTTP/1.1
Content-Type: application/json
X-GSH-Signature: sha256=a1b2c3d4e5f6...
User-Agent: GoSignHere-Webhook/1.0

Signature Verification

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.

Verification
# 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

Retry Policy

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.

AttemptDelayTotal Elapsed
1Immediate0
21 minute1 min
35 minutes6 min
430 minutes36 min
52 hours~2.5 hrs
68 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.

Best Practices
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.