GoSignHere API reference
Getting started
Integrate GoSignHere into your workflow
GoSignHere has an API, so it fits into your business and workflows and works with your other products through it.
Create an API key
- Sign in to GoSignHere as an owner or admin.
- Open Settings, then API and webhooks.
- Choose Create key, name it for the system that will use it, and copy the key now. It is shown once.
- Send it with every request as
Authorization: Bearer gsh_live_....
Every route below is under /api/v1. Successful responses are {"data": ...}; errors are {"error": {"code", "message", "field"}}. The same reference is available as openapi.json.
Base URL: https://app.gosignhere.com. Send JSON with Content-Type: application/json; uploads are multipart/form-data. A first call:
curl
curl 'https://app.gosignhere.com/api/v1/auth/me' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/auth/me', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/me', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/me', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/me');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Send a document for signature
POST /api/v1/documents with the file. Wait until render_status is ready.
- Place the signing fields once in the app (or with
PUT /api/v1/documents/{id}/fields); mark the document as a template if you reuse it.
POST /api/v1/packages with the document_id and the signers. They get the email at once.
- Listen for webhooks, or poll
GET /api/v1/packages/{id}. When it completes, download completed.pdf.
Errors
Every failure has a 4xx or 5xx status and one envelope. field is present when one input is at fault.
{"error": {"code": "validation_failed", "message": "Add between 1 and 8 signers.", "field": "signers"}}
| Code | HTTP | When |
validation_failed | 422 | A field is missing or malformed; "field" names it. |
bad_request | 400 | The request itself is malformed (for example a bad If-Match value). |
invalid_api_key | 401 | The bearer key is unknown or revoked. |
unauthenticated | 401 | No key and no session. |
invalid_credentials | 401 | Wrong email or password. |
forbidden | 403 | Your role or folder access cannot do this. |
session_required | 403 | The route needs a signed-in session; API keys are refused. |
plan_api_disabled | 403 | The account plan does not include API access. |
email_unverified | 403 | Confirm the sender address before sending documents. |
csrf_failed | 403 | A session call without a valid X-CSRF header (key calls never need it). |
not_found | 404 | No such object in your account. |
document_not_ready | 409 | The document is still rendering, or archived. |
document_locked | 409 | A sent package uses the document, so its file cannot change. |
duplicate_document | 409 | This file was already uploaded. |
not_draft | 409 | Only a draft package can be edited this way. |
not_editable | 409 | The package or signer can no longer be changed. |
not_voidable | 409 | Only a package in progress can be voided. |
not_completed | 409 | The package has not completed, so it has no signed PDF yet. |
not_ready | 409 | The package has a problem; GET /validate lists it. |
package_closed | 409 | The package is completed, declined, voided or expired. |
slug_taken | 409 | That name is already used. |
precondition_required | 428 | A fields write without If-Match: send the fields_revision you loaded. |
no_fields | 422 | The document has no fields to sign. |
signer_missing | 422 | A role with fields has no signer. |
role_without_fields | 422 | A signer has no fields on the document. |
bad_hash | 422 | A SHA-256 is 64 hexadecimal characters. |
file_too_large | 413 | Uploads are limited to 25 MB. |
send_cap_reached | 429 | The plan's monthly send limit is used up. |
rate_limited | 429 | Too many requests; see Retry-After. |
server_error | 500 | Something went wrong on our side; safe to retry reads. |
render_busy | 503 | The PDF renderer is busy; retry in a few seconds. |
Rate limits
Each IP address may make 600 requests per minute to the API. Sending is limited to 60 packages per hour per user, and signer resends to 20 per hour per package. Over a limit the answer is 429 with code rate_limited and a Retry-After header in seconds; wait that long, then retry. Plans also cap sends per month (send_cap_reached).
Webhooks
Set a webhook URL under Settings, API and webhooks. We POST a JSON body to it when a package changes state. Answer with any 2xx; anything else is retried 3 times, 2 then 4 minutes apart.
Events:
package.completed
package.declined
package.voided
package.test
{
"event": "package.completed",
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "completed",
"title": "Services agreement",
"completed_at": "2026-10-10T10:45:00Z",
"pdf_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"verify_url": "https://app.gosignhere.com/verify/3f6c1c52-8b0e-4c1a-9a53-0d2f6c1b7e10"
}
}
Headers: X-GSH-Event, X-GSH-Delivery (a unique id; use it to ignore repeats) and X-GSH-Signature: sha256=<hex>. The signature is the HMAC-SHA256 of the exact raw request body, keyed with your webhook secret (Settings, API and webhooks). Compute it over the raw bytes before parsing the JSON, compare in constant time, and reject a mismatch with 400.
curl
# Queue a package.test delivery to your webhook URL (signed like a real one)
curl -X POST 'https://app.gosignhere.com/api/v1/account/settings/webhook-test' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import hashlib, hmac
def is_genuine(raw_body: bytes, header: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)
# Flask: is_genuine(request.get_data(), request.headers['X-GSH-Signature'], WEBHOOK_SECRET)
JavaScript
// Runs anywhere with WebCrypto (Cloudflare Workers, Deno, browsers). Keep the secret server-side.
async function isGenuine(rawBody, header, secret) {
const key = await crypto.subtle.importKey('raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
const mac = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(rawBody));
const hex = [...new Uint8Array(mac)].map(b => b.toString(16).padStart(2, '0')).join('');
return header === 'sha256=' + hex;
}
Node.js
const crypto = require('node:crypto');
function isGenuine(rawBody, header, secret) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const a = Buffer.from(expected), b = Buffer.from(header || '');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// Express: app.post('/hooks/gsh', express.raw({ type: 'application/json' }), (req, res) => {
// if (!isGenuine(req.body, req.get('X-GSH-Signature'), process.env.GSH_WEBHOOK_SECRET)) return res.sendStatus(400);
// res.sendStatus(204); });
PHP
<?php
$raw = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $raw, getenv('GSH_WEBHOOK_SECRET'));
if (!hash_equals($expected, $_SERVER['HTTP_X_GSH_SIGNATURE'] ?? '')) {
http_response_code(400);
exit;
}
$event = json_decode($raw, true); // $event['event'], $event['package']['verify_url'], ...
http_response_code(204);
Validate a signed PDF
Anyone can check a signed PDF without an account at https://app.gosignhere.com/verify/{id}: drop the file on the page and your browser fingerprints it (nothing is uploaded) and compares it with the sealed PDF's SHA-256.
The id is the package's GUID (the same value the package's API id carries). You get it as verify_url in every webhook payload, in the completed mail the signers and sender receive, and from the keyed route GET /api/v1/packages/{id}/verify, which also returns pdf_sha256, the SHA-256 of the sealed PDF. A copy is genuine when its own SHA-256 equals pdf_sha256. To let the server do the comparison, add ?hash=<sha256 of your copy> to that route; the answer says whether it matches.
Fetch the package's verification record and print the two values:
curl
curl 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
| jq -r '.data | .verify_url, .pdf_sha256'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify', headers=headers)
r.raise_for_status()
d = r.json()['data']
print(d['verify_url'])
print(d['pdf_sha256'])
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
const { data } = await res.json();
console.log(data.verify_url);
console.log(data.pdf_sha256);
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
const { data } = await res.json();
console.log(data.verify_url);
console.log(data.pdf_sha256);
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
$data = json_decode($out, true)['data'];
echo $data['verify_url'], "\n", $data['pdf_sha256'], "\n"; // HTTP $status, body {"data": ...}
Reference
Authentication notes: API key or session routes accept Authorization: Bearer gsh_live_...; Signed-in session only routes refuse keys (session_required) and need the session cookie plus an X-CSRF header on writes; No key needed routes are open. Success bodies are {"data": ...}. Placeholders such as {id} are shown as a sample GUID (018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f) in the samples; page numbers are plain integers.
Account
GET /api/v1/account #
API key or session.
The account: name, plan, usage.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/account' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/account', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/account');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"account": {
"id": "018f6c1e-7b31-7c4d-8e3f-7a8b9caebfc0",
"name": "Analytical Engines Ltd",
"type": "business",
"plan": "beta"
}
}
}
PATCH /api/v1/account #
Signed-in session only (API keys are refused). Roles: owner, admin.
Rename the account.
| Name | Type | | Description |
name | string | required | 2 to 120 characters. |
curl
curl -X PATCH 'https://app.gosignhere.com/api/v1/account' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Analytical Engines Inc"}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'name': 'Analytical Engines Inc',
}
r = requests.patch('https://app.gosignhere.com/api/v1/account', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account', {
method: 'PATCH',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Analytical Engines Inc"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account', {
method: 'PATCH',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Analytical Engines Inc"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'name' => 'Analytical Engines Inc',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/account');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"account": {
"id": "018f6c1e-7b31-7c4d-8e3f-7a8b9caebfc0",
"name": "Analytical Engines Inc"
}
}
}
DELETE /api/v1/account #
Signed-in session only (API keys are refused). Roles: owner.
Delete the account and everything in it. Owner only; needs the password.
| Name | Type | | Description |
password | string | required | The owner's password. |
curl
curl -X DELETE 'https://app.gosignhere.com/api/v1/account' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"password":"a long passphrase here"}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'password': 'a long passphrase here',
}
r = requests.delete('https://app.gosignhere.com/api/v1/account', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account', {
method: 'DELETE',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account', {
method: 'DELETE',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'password' => 'a long passphrase here',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/account');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"deleted": true
}
}
GET /api/v1/account/settings #
API key or session.
Sending defaults, notification switches and the webhook URL.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/account/settings' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/account/settings', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/settings', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/settings', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/account/settings');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"settings": {
"default_expiry_days": 30,
"reminder_days": 3,
"default_subject": "",
"default_message": "",
"notify_viewed": false,
"notify_signed": true,
"notify_completed": true,
"notify_declined": true,
"webhook_url": "https://example.com/hooks/gsh",
"webhook_secret_set": true
}
}
}
PATCH /api/v1/account/settings #
Signed-in session only (API keys are refused). Roles: owner, admin.
Change any of the settings; only the keys you send change.
| Name | Type | | Description |
webhook_url | string | optional | HTTPS URL for webhooks; empty clears it. |
default_expiry_days | integer | optional | 0 (never) to 365. |
reminder_days | integer | optional | Days between reminders; 0 turns them off. |
default_subject | string | optional | Email subject for new packages. |
default_message | string | optional | Message for new packages. |
notify_signed | boolean | optional | Email me when someone signs. |
curl
curl -X PATCH 'https://app.gosignhere.com/api/v1/account/settings' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"webhook_url":"https://example.com/hooks/gsh","default_expiry_days":14}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'webhook_url': 'https://example.com/hooks/gsh',
'default_expiry_days': 14,
}
r = requests.patch('https://app.gosignhere.com/api/v1/account/settings', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/settings', {
method: 'PATCH',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"webhook_url": "https://example.com/hooks/gsh",
"default_expiry_days": 14
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/settings', {
method: 'PATCH',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"webhook_url": "https://example.com/hooks/gsh",
"default_expiry_days": 14
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'webhook_url' => 'https://example.com/hooks/gsh',
'default_expiry_days' => 14,
];
$ch = curl_init('https://app.gosignhere.com/api/v1/account/settings');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"settings": {
"default_expiry_days": 30,
"reminder_days": 3,
"default_subject": "",
"default_message": "",
"notify_viewed": false,
"notify_signed": true,
"notify_completed": true,
"notify_declined": true,
"webhook_url": "https://example.com/hooks/gsh",
"webhook_secret_set": true
}
}
}
POST /api/v1/account/settings/webhook-test #
Signed-in session only (API keys are refused). Roles: owner, admin.
Queue a package.test delivery to your webhook URL.
No request fields.
curl
curl -X POST 'https://app.gosignhere.com/api/v1/account/settings/webhook-test' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
r = requests.post('https://app.gosignhere.com/api/v1/account/settings/webhook-test', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/settings/webhook-test', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/settings/webhook-test', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/account/settings/webhook-test');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 202
{
"data": {
"delivery": {
"id": "018f6c1e-7b33-7c4d-8e3f-9aabbcd0d1e2",
"event": "package.test",
"status": "queued"
}
}
}
GET /api/v1/account/users #
Signed-in session only (API keys are refused).
The people on the account.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/account/users' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
r = requests.get('https://app.gosignhere.com/api/v1/account/users', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/users', {
method: 'GET',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/users', {
method: 'GET',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/account/users');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"users": [
{
"id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"name": "Grace Hopper",
"email": "grace@example.com",
"role": "admin",
"status": "active"
}
]
}
}
POST /api/v1/account/users/invite #
Signed-in session only (API keys are refused). Roles: owner, admin.
Invite a teammate by email.
| Name | Type | | Description |
email | string | required | Their address. |
name | string | optional | Their name. |
role | string | optional | admin or member. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/account/users/invite' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"email":"grace@example.com","name":"Grace Hopper","role":"member"}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'email': 'grace@example.com',
'name': 'Grace Hopper',
'role': 'member',
}
r = requests.post('https://app.gosignhere.com/api/v1/account/users/invite', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/users/invite', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "grace@example.com",
"name": "Grace Hopper",
"role": "member"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/users/invite', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "grace@example.com",
"name": "Grace Hopper",
"role": "member"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'email' => 'grace@example.com',
'name' => 'Grace Hopper',
'role' => 'member',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/account/users/invite');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 201
{
"data": {
"user": {
"id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"name": "Grace Hopper",
"email": "grace@example.com",
"role": "admin",
"status": "active"
}
}
}
POST /api/v1/account/users/{id}/resend-invite #
Signed-in session only (API keys are refused). Roles: owner, admin.
Send a pending invitation again.
No request fields.
curl
curl -X POST 'https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf/resend-invite' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
r = requests.post('https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf/resend-invite', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf/resend-invite', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf/resend-invite', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf/resend-invite');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"sent": true
}
}
PATCH /api/v1/account/users/{id} #
Signed-in session only (API keys are refused). Roles: owner, admin.
Change a teammate's role or switch them off.
| Name | Type | | Description |
role | string | optional | admin or member. |
active | boolean | optional | false disables the user. |
curl
curl -X PATCH 'https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"role":"admin"}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'role': 'admin',
}
r = requests.patch('https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf', {
method: 'PATCH',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"role": "admin"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf', {
method: 'PATCH',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"role": "admin"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'role' => 'admin',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/account/users/018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"user": {
"id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"name": "Grace Hopper",
"email": "grace@example.com",
"role": "admin",
"status": "active"
}
}
}
POST /api/v1/account/transfer-ownership #
Signed-in session only (API keys are refused). Roles: owner.
Hand the account to another user. Owner only; needs the password.
| Name | Type | | Description |
user_id | uuid | required | The new owner. |
password | string | required | Your password. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/account/transfer-ownership' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"user_id":"018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf","password":"a long passphrase here"}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'user_id': '018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf',
'password': 'a long passphrase here',
}
r = requests.post('https://app.gosignhere.com/api/v1/account/transfer-ownership', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/transfer-ownership', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"user_id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/transfer-ownership', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"user_id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'user_id' => '018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf',
'password' => 'a long passphrase here',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/account/transfer-ownership');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"transferred": true
}
}
GET /api/v1/account/api-keys #
Signed-in session only (API keys are refused). Roles: owner, admin.
Your API keys (prefix and last use only, never the secret).
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/account/api-keys' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
r = requests.get('https://app.gosignhere.com/api/v1/account/api-keys', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/api-keys', {
method: 'GET',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/api-keys', {
method: 'GET',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/account/api-keys');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"keys": [
{
"id": "018f6c1e-7b32-7c4d-8e3f-8a9babcfc0d1",
"name": "CRM sync",
"prefix": "gsh_live_ab12",
"created_at": "2026-10-10T09:00:00Z",
"last_used_at": null
}
]
}
}
POST /api/v1/account/api-keys #
Signed-in session only (API keys are refused). Roles: owner, admin.
Create a key. The full key is in this response only.
| Name | Type | | Description |
name | string | required | What the key is for. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/account/api-keys' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"CRM sync"}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'name': 'CRM sync',
}
r = requests.post('https://app.gosignhere.com/api/v1/account/api-keys', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/api-keys', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "CRM sync"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/api-keys', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "CRM sync"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'name' => 'CRM sync',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/account/api-keys');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 201
{
"data": {
"id": "018f6c1e-7b32-7c4d-8e3f-8a9babcfc0d1",
"name": "CRM sync",
"prefix": "gsh_live_ab12",
"key": "gsh_live_ab12EXAMPLEEXAMPLEEXAMPLE"
}
}
DELETE /api/v1/account/api-keys/{id} #
Signed-in session only (API keys are refused). Roles: owner, admin.
Revoke a key. It stops working at once.
No request fields.
curl
curl -X DELETE 'https://app.gosignhere.com/api/v1/account/api-keys/018f6c1e-7b32-7c4d-8e3f-8a9babcfc0d1' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
r = requests.delete('https://app.gosignhere.com/api/v1/account/api-keys/018f6c1e-7b32-7c4d-8e3f-8a9babcfc0d1', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/api-keys/018f6c1e-7b32-7c4d-8e3f-8a9babcfc0d1', {
method: 'DELETE',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/account/api-keys/018f6c1e-7b32-7c4d-8e3f-8a9babcfc0d1', {
method: 'DELETE',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/account/api-keys/018f6c1e-7b32-7c4d-8e3f-8a9babcfc0d1');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"revoked": true
}
}
Auth
POST /api/v1/auth/register #
No key needed.
Create an account and its first owner. A confirmation email follows.
| Name | Type | | Description |
name | string | required | Your name, up to 120 characters. |
email | string | required | Sign-in address. |
password | string | required | At least 10 characters. |
account_name | string | required | Company or workspace name. |
account_type | string | required | business or personal. |
invite_code | string | optional | Only when registration is closed. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/register' \
-H 'Content-Type: application/json' \
-d '{"name":"Ada Lovelace","email":"ada@example.com","password":"a long passphrase here","account_name":"Analytical Engines Ltd","account_type":"business"}'
Python
import requests
payload = {
'name': 'Ada Lovelace',
'email': 'ada@example.com',
'password': 'a long passphrase here',
'account_name': 'Analytical Engines Ltd',
'account_type': 'business',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/register', json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Ada Lovelace",
"email": "ada@example.com",
"password": "a long passphrase here",
"account_name": "Analytical Engines Ltd",
"account_type": "business"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Ada Lovelace",
"email": "ada@example.com",
"password": "a long passphrase here",
"account_name": "Analytical Engines Ltd",
"account_type": "business"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'name' => 'Ada Lovelace',
'email' => 'ada@example.com',
'password' => 'a long passphrase here',
'account_name' => 'Analytical Engines Ltd',
'account_type' => 'business',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/register');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 201
{
"data": {
"user": {
"id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"name": "Ada Lovelace",
"email": "ada@example.com",
"role": "owner"
},
"verification_sent": true
}
}
POST /api/v1/auth/verify-email #
No key needed.
Confirm an email address with the token from the email.
| Name | Type | | Description |
token | string | required | From the confirmation link. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/verify-email' \
-H 'Content-Type: application/json' \
-d '{"token":"tok_EXAMPLE"}'
Python
import requests
payload = {
'token': 'tok_EXAMPLE',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/verify-email', json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/verify-email', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"token": "tok_EXAMPLE"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/verify-email', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"token": "tok_EXAMPLE"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'token' => 'tok_EXAMPLE',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/verify-email');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"verified": true
}
}
POST /api/v1/auth/verify-email/resend #
No key needed.
Send the confirmation email again.
| Name | Type | | Description |
email | string | required | The address to confirm. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/verify-email/resend' \
-H 'Content-Type: application/json' \
-d '{"email":"ada@example.com"}'
Python
import requests
payload = {
'email': 'ada@example.com',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/verify-email/resend', json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/verify-email/resend', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "ada@example.com"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/verify-email/resend', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "ada@example.com"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'email' => 'ada@example.com',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/verify-email/resend');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"sent": true
}
}
POST /api/v1/auth/login #
No key needed.
Start a session. Returns the CSRF token to send as X-CSRF on later writes; the session cookie is set.
| Name | Type | | Description |
email | string | required | Account email. |
password | string | required | Account password. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/login' \
-H 'Content-Type: application/json' \
-d '{"email":"ada@example.com","password":"a long passphrase here"}'
Python
import requests
payload = {
'email': 'ada@example.com',
'password': 'a long passphrase here',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/login', json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "ada@example.com",
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "ada@example.com",
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'email' => 'ada@example.com',
'password' => 'a long passphrase here',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/login');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"user": {
"id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"name": "Ada Lovelace",
"role": "owner"
},
"csrf": "EXAMPLE_CSRF_TOKEN"
}
}
POST /api/v1/auth/logout #
Signed-in session only (API keys are refused).
End the session.
No request fields.
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/logout' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/logout', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/logout', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/logout', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/logout');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"logged_out": true
}
}
GET /api/v1/auth/me #
API key or session.
The signed-in user and account (works with a key too).
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/auth/me' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/auth/me', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/me', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/me', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/me');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"user": {
"id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"name": "Grace Hopper",
"email": "grace@example.com",
"role": "admin",
"status": "active"
},
"account": {
"id": "018f6c1e-7b31-7c4d-8e3f-7a8b9caebfc0",
"name": "Analytical Engines Ltd",
"plan": "beta"
}
}
}
POST /api/v1/auth/password/forgot #
No key needed.
Email a password reset link. Always answers the same, whether or not the address exists.
| Name | Type | | Description |
email | string | required | Account email. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/password/forgot' \
-H 'Content-Type: application/json' \
-d '{"email":"ada@example.com"}'
Python
import requests
payload = {
'email': 'ada@example.com',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/password/forgot', json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/password/forgot', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "ada@example.com"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/password/forgot', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "ada@example.com"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'email' => 'ada@example.com',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/password/forgot');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"sent": true
}
}
POST /api/v1/auth/password/reset #
No key needed.
Set a new password with the token from the reset email.
| Name | Type | | Description |
token | string | required | From the reset link. |
password | string | required | The new password. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/password/reset' \
-H 'Content-Type: application/json' \
-d '{"token":"tok_EXAMPLE","password":"a new long passphrase"}'
Python
import requests
payload = {
'token': 'tok_EXAMPLE',
'password': 'a new long passphrase',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/password/reset', json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/password/reset', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"token": "tok_EXAMPLE",
"password": "a new long passphrase"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/password/reset', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"token": "tok_EXAMPLE",
"password": "a new long passphrase"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'token' => 'tok_EXAMPLE',
'password' => 'a new long passphrase',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/password/reset');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"reset": true
}
}
POST /api/v1/auth/password/change #
Signed-in session only (API keys are refused).
Change your password. Other sessions end.
| Name | Type | | Description |
current_password | string | required | The password now. |
new_password | string | required | The new password. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/password/change' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"current_password":"old passphrase","new_password":"a new long passphrase"}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'current_password': 'old passphrase',
'new_password': 'a new long passphrase',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/password/change', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/password/change', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"current_password": "old passphrase",
"new_password": "a new long passphrase"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/password/change', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"current_password": "old passphrase",
"new_password": "a new long passphrase"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'current_password' => 'old passphrase',
'new_password' => 'a new long passphrase',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/password/change');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"changed": true
}
}
POST /api/v1/auth/email/change #
Signed-in session only (API keys are refused).
Start an email change; the new address must confirm.
| Name | Type | | Description |
new_email | string | required | The new address. |
password | string | required | Your password. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/email/change' \
-H 'Cookie: gsh_s=YOUR_SESSION' \
-H 'X-CSRF: YOUR_CSRF_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"new_email":"ada@new.example.com","password":"a long passphrase here"}'
Python
import requests
headers = {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
}
payload = {
'new_email': 'ada@new.example.com',
'password': 'a long passphrase here',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/email/change', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/email/change', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"new_email": "ada@new.example.com",
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/email/change', {
method: 'POST',
headers: {
'Cookie': 'gsh_s=YOUR_SESSION',
'X-CSRF': 'YOUR_CSRF_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"new_email": "ada@new.example.com",
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'new_email' => 'ada@new.example.com',
'password' => 'a long passphrase here',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/email/change');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Cookie: gsh_s=YOUR_SESSION',
'X-CSRF: YOUR_CSRF_TOKEN',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"sent": true
}
}
POST /api/v1/auth/invite/accept #
No key needed.
Accept a team invitation: set your name and password.
| Name | Type | | Description |
token | string | required | From the invitation email. |
name | string | required | Your name. |
password | string | required | Your password. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/auth/invite/accept' \
-H 'Content-Type: application/json' \
-d '{"token":"tok_EXAMPLE","name":"Grace Hopper","password":"a long passphrase here"}'
Python
import requests
payload = {
'token': 'tok_EXAMPLE',
'name': 'Grace Hopper',
'password': 'a long passphrase here',
}
r = requests.post('https://app.gosignhere.com/api/v1/auth/invite/accept', json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/invite/accept', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"token": "tok_EXAMPLE",
"name": "Grace Hopper",
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/auth/invite/accept', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"token": "tok_EXAMPLE",
"name": "Grace Hopper",
"password": "a long passphrase here"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'token' => 'tok_EXAMPLE',
'name' => 'Grace Hopper',
'password' => 'a long passphrase here',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/auth/invite/accept');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"accepted": true
}
}
Documents
GET /api/v1/documents #
API key or session.
List documents. Filter with the query parameters.
| Name | Type | | Description |
folder_id query | uuid | optional | Only this folder. |
q query | string | optional | Search the title. |
status query | string | optional | draft, ready or archived. |
curl
curl 'https://app.gosignhere.com/api/v1/documents?folder_id=018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/documents?folder_id=018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents?folder_id=018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents?folder_id=018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/documents?folder_id=018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"documents": [
{
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"status": "ready",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"tags": [],
"render_status": "ready",
"render_error": null,
"page_count": 3,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
]
}
}
GET /api/v1/documents/{id} #
API key or session.
One document and its processing state.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"document": {
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"status": "ready",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"tags": [],
"render_status": "ready",
"render_error": null,
"page_count": 3,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
}
}
PATCH /api/v1/documents/{id} #
API key or session.
Rename or move a document.
| Name | Type | | Description |
title | string | optional | New title. |
folder_id | uuid | optional | New folder. |
curl
curl -X PATCH 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"title":"Services agreement v2"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'title': 'Services agreement v2',
}
r = requests.patch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Services agreement v2"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Services agreement v2"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'title' => 'Services agreement v2',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"document": {
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"status": "ready",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"tags": [],
"render_status": "ready",
"render_error": null,
"page_count": 3,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
}
}
POST /api/v1/documents/{id}/archive #
API key or session.
Archive a document (it leaves the library; sent packages keep their copy).
No request fields.
curl
curl -X POST 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/archive' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.post('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/archive', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/archive', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/archive', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/archive');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"document": {
"status": "archived",
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"tags": [],
"render_status": "ready",
"render_error": null,
"page_count": 3,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
}
}
PUT /api/v1/documents/{id}/tags #
API key or session.
Replace the document's tags.
| Name | Type | | Description |
tags | array | required | Tag ids. |
curl
curl -X PUT 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/tags' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"tags":["018f6c1e-7b2f-7c4d-8e3f-5a6b7c8d9eaf"]}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'tags': [
'018f6c1e-7b2f-7c4d-8e3f-5a6b7c8d9eaf',
],
}
r = requests.put('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/tags', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/tags', {
method: 'PUT',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"tags": [
"018f6c1e-7b2f-7c4d-8e3f-5a6b7c8d9eaf"
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/tags', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"tags": [
"018f6c1e-7b2f-7c4d-8e3f-5a6b7c8d9eaf"
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'tags' => [
'018f6c1e-7b2f-7c4d-8e3f-5a6b7c8d9eaf',
],
];
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/tags');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"document": {
"tags": [
{
"id": "018f6c1e-7b2f-7c4d-8e3f-5a6b7c8d9eaf",
"name": "Legal"
}
],
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"status": "ready",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"render_status": "ready",
"render_error": null,
"page_count": 3,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
}
}
POST /api/v1/documents #
API key or session.
Upload a document (PDF, Word, Excel, PowerPoint, OpenDocument, RTF, text, PNG or JPG; 25 MB) as multipart, or create one from HTML as JSON. Rendering is asynchronous: poll GET /documents/{id} until render_status is ready.
| Name | Type | | Description |
file | file | required | Multipart form field. |
folder_id | uuid | optional | Target folder; defaults to your home folder. |
title | string | optional | Defaults to the file name. Required with html. |
html | string | optional | JSON alternative to file: the document body as HTML. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/documents' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-F 'file=@agreement.pdf' \
-F 'folder_id=018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.post('https://app.gosignhere.com/api/v1/documents', headers=headers, files={'file': open('agreement.pdf', 'rb')}, data={'folder_id': '018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f'})
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const form = new FormData();
form.append('file', fileInput.files[0]); // an <input type="file">
form.append('folder_id', '018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f');
const res = await fetch('https://app.gosignhere.com/api/v1/documents', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
body: form,
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
const fs = require('node:fs');
async function main() {
const form = new FormData();
form.append('file', new Blob([fs.readFileSync('agreement.pdf')]), 'agreement.pdf');
form.append('folder_id', '018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f');
const res = await fetch('https://app.gosignhere.com/api/v1/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
body: form,
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$form = [
'file' => new CURLFile('agreement.pdf'),
'folder_id' => '018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/documents');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
CURLOPT_POSTFIELDS => $form,
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 201
{
"data": {
"document": {
"render_status": "queued",
"page_count": null,
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"status": "ready",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"tags": [],
"render_error": null,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
}
}
POST /api/v1/documents/{id}/file #
API key or session.
Replace the file. Refused when a sent package already uses the document.
| Name | Type | | Description |
file | file | required | Multipart form field. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/file' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-F 'file=@agreement-v2.pdf'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.post('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/file', headers=headers, files={'file': open('agreement-v2.pdf', 'rb')})
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const form = new FormData();
form.append('file', fileInput.files[0]); // an <input type="file">
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/file', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
body: form,
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
const fs = require('node:fs');
async function main() {
const form = new FormData();
form.append('file', new Blob([fs.readFileSync('agreement-v2.pdf')]), 'agreement-v2.pdf');
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/file', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
body: form,
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$form = [
'file' => new CURLFile('agreement-v2.pdf'),
];
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/file');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
CURLOPT_POSTFIELDS => $form,
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"document": {
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"status": "ready",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"tags": [],
"render_status": "ready",
"render_error": null,
"page_count": 3,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
}
}
GET /api/v1/documents/{id}/pages/{p} #
API key or session.
A rendered page image (PNG).
No request fields.
curl
curl -o out.png 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/pages/1' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/pages/1', headers=headers)
r.raise_for_status()
open('out.png', 'wb').write(r.content)
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/pages/1', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
const file = await res.blob(); // save or display it
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/pages/1', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
require('node:fs').writeFileSync('out.png', Buffer.from(await res.arrayBuffer()));
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/pages/1');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
file_put_contents('out.png', $out);
Response 200
The file itself (image/png), not JSON.
GET /api/v1/documents/{id}/fields #
API key or session.
The signing fields and the fields_revision to send back as If-Match.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"fields_revision": 4,
"roles": [
{
"role": "R1",
"label": "Client"
}
],
"fields": [
{
"id": "018f6c1e-7b34-7c4d-8e3f-0abbcdd1e2f3",
"field_key": "client_signature",
"field_type": "signature",
"label": "Client signature",
"recipient_role": "R1",
"page": 1,
"x_bp": 1000,
"y_bp": 8000,
"w_bp": 3000,
"h_bp": 700,
"required": true
}
]
}
}
PUT /api/v1/documents/{id}/fields #
API key or session.
Replace the document's fields. Positions are basis points (0 to 10000) of the page. Send If-Match: the fields_revision you loaded.
| Name | Type | | Description |
fields | array | required | field_key, field_type (signature, initials, date, text, checkbox), recipient_role, page, x_bp, y_bp, w_bp, h_bp, required, label. |
curl
curl -X PUT 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'If-Match: 4' \
-H 'Content-Type: application/json' \
-d '{"fields":[{"field_key":"client_signature","field_type":"signature","label":"Client signature","recipient_role":"R1","page":1,"x_bp":1000,"y_bp":8000,"w_bp":3000,"h_bp":700,"required":true}]}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'If-Match': '4',
}
payload = {
'fields': [
{
'field_key': 'client_signature',
'field_type': 'signature',
'label': 'Client signature',
'recipient_role': 'R1',
'page': 1,
'x_bp': 1000,
'y_bp': 8000,
'w_bp': 3000,
'h_bp': 700,
'required': True,
},
],
}
r = requests.put('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields', {
method: 'PUT',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'If-Match': '4',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"fields": [
{
"field_key": "client_signature",
"field_type": "signature",
"label": "Client signature",
"recipient_role": "R1",
"page": 1,
"x_bp": 1000,
"y_bp": 8000,
"w_bp": 3000,
"h_bp": 700,
"required": true
}
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'If-Match': '4',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"fields": [
{
"field_key": "client_signature",
"field_type": "signature",
"label": "Client signature",
"recipient_role": "R1",
"page": 1,
"x_bp": 1000,
"y_bp": 8000,
"w_bp": 3000,
"h_bp": 700,
"required": true
}
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'fields' => [
[
'field_key' => 'client_signature',
'field_type' => 'signature',
'label' => 'Client signature',
'recipient_role' => 'R1',
'page' => 1,
'x_bp' => 1000,
'y_bp' => 8000,
'w_bp' => 3000,
'h_bp' => 700,
'required' => true,
],
],
];
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/fields');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'If-Match: 4',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"fields_revision": 5,
"fields": [
{
"id": "018f6c1e-7b34-7c4d-8e3f-0abbcdd1e2f3",
"field_key": "client_signature"
}
]
}
}
PUT /api/v1/documents/{id}/roles #
API key or session.
Name the signing roles (R1, R2, ...) of the document.
| Name | Type | | Description |
roles | array | required | Objects with role and label. |
curl
curl -X PUT 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/roles' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"roles":[{"role":"R1","label":"Client"}]}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'roles': [
{
'role': 'R1',
'label': 'Client',
},
],
}
r = requests.put('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/roles', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/roles', {
method: 'PUT',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"roles": [
{
"role": "R1",
"label": "Client"
}
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/roles', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"roles": [
{
"role": "R1",
"label": "Client"
}
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'roles' => [
[
'role' => 'R1',
'label' => 'Client',
],
],
];
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/roles');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"roles": [
{
"role": "R1",
"label": "Client"
}
]
}
}
GET /api/v1/documents/{id}/preview.pdf #
API key or session.
The document with its fields drawn on, as a PDF.
No request fields.
curl
curl -o out.pdf 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/preview.pdf' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/preview.pdf', headers=headers)
r.raise_for_status()
open('out.pdf', 'wb').write(r.content)
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/preview.pdf', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
const file = await res.blob(); // save or display it
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/preview.pdf', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
require('node:fs').writeFileSync('out.pdf', Buffer.from(await res.arrayBuffer()));
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/preview.pdf');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
file_put_contents('out.pdf', $out);
Response 200
The file itself (application/pdf), not JSON.
PUT /api/v1/documents/{id}/template #
API key or session.
Mark or unmark the document as a reusable template.
| Name | Type | | Description |
is_template | boolean | required | true or false. |
curl
curl -X PUT 'https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/template' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"is_template":true}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'is_template': True,
}
r = requests.put('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/template', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/template', {
method: 'PUT',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"is_template": true
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/template', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"is_template": true
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'is_template' => true,
];
$ch = curl_init('https://app.gosignhere.com/api/v1/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f/template');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"document": {
"is_template": true,
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"status": "ready",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"tags": [],
"render_status": "ready",
"render_error": null,
"page_count": 3,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
}
}
Folders
GET /api/v1/folders #
API key or session.
The folders you can see.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/folders' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/folders', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/folders');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"folders": [
{
"id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"name": "Contracts",
"parent_id": null,
"is_default": false
}
]
}
}
POST /api/v1/folders #
API key or session.
Create a folder.
| Name | Type | | Description |
name | string | required | Up to 120 characters. |
parent_id | uuid | optional | Nest it inside another folder. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/folders' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"name":"Contracts"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'name': 'Contracts',
}
r = requests.post('https://app.gosignhere.com/api/v1/folders', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Contracts"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Contracts"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'name' => 'Contracts',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/folders');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 201
{
"data": {
"folder": {
"id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"name": "Contracts",
"parent_id": null,
"is_default": false
}
}
}
GET /api/v1/folders/{id} #
API key or session.
One folder.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"folder": {
"id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"name": "Contracts",
"parent_id": null,
"is_default": false
}
}
}
PATCH /api/v1/folders/{id} #
API key or session.
Rename or move a folder.
| Name | Type | | Description |
name | string | optional | New name. |
parent_id | uuid | optional | New parent. |
curl
curl -X PATCH 'https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"name":"Signed contracts"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'name': 'Signed contracts',
}
r = requests.patch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Signed contracts"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Signed contracts"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'name' => 'Signed contracts',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"folder": {
"id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"name": "Contracts",
"parent_id": null,
"is_default": false
}
}
}
DELETE /api/v1/folders/{id} #
API key or session.
Delete an empty folder.
No request fields.
curl
curl -X DELETE 'https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.delete('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"deleted": true
}
}
GET /api/v1/folders/{id}/shares #
API key or session.
Who else can see or edit the folder.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"shares": [
{
"user_id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"access": "edit"
}
]
}
}
PUT /api/v1/folders/{id}/shares #
API key or session.
Replace the folder's share list.
| Name | Type | | Description |
shares | array | required | Objects with user_id and access (view or edit). |
curl
curl -X PUT 'https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"shares":[{"user_id":"018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf","access":"edit"}]}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'shares': [
{
'user_id': '018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf',
'access': 'edit',
},
],
}
r = requests.put('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares', {
method: 'PUT',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"shares": [
{
"user_id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"access": "edit"
}
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"shares": [
{
"user_id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"access": "edit"
}
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'shares' => [
[
'user_id' => '018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf',
'access' => 'edit',
],
],
];
$ch = curl_init('https://app.gosignhere.com/api/v1/folders/018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f/shares');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"shares": [
{
"user_id": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"access": "edit"
}
]
}
}
Packages
POST /api/v1/packages #
API key or session.
Send a document for signature in one call: pass document_id and signers. For several documents, a draft, or per-signer kinds, pass documents (a list of ids) and optionally send:true.
| Name | Type | | Description |
document_id | uuid | required | A ready document with fields placed. |
signers | array | required | 1 to 8 objects: role (R1...), name, email. |
title | string | optional | Defaults to the document title. |
message | string | optional | Up to 2,000 characters. |
expires_in_days | integer | optional | 0 (never) to 365. |
documents | array | optional | Assembly form: document ids; with signers (kind signer, approver or cc) and send. |
draft | boolean | optional | Create a draft, do not send. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/packages' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"document_id":"018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f","title":"Services agreement","message":"Please sign by Friday.","signers":[{"role":"R1","name":"Ada Lovelace","email":"ada@example.com"}]}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'document_id': '018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f',
'title': 'Services agreement',
'message': 'Please sign by Friday.',
'signers': [
{
'role': 'R1',
'name': 'Ada Lovelace',
'email': 'ada@example.com',
},
],
}
r = requests.post('https://app.gosignhere.com/api/v1/packages', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"message": "Please sign by Friday.",
"signers": [
{
"role": "R1",
"name": "Ada Lovelace",
"email": "ada@example.com"
}
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"message": "Please sign by Friday.",
"signers": [
{
"role": "R1",
"name": "Ada Lovelace",
"email": "ada@example.com"
}
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'document_id' => '018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f',
'title' => 'Services agreement',
'message' => 'Please sign by Friday.',
'signers' => [
[
'role' => 'R1',
'name' => 'Ada Lovelace',
'email' => 'ada@example.com',
],
],
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 201
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
GET /api/v1/packages #
API key or session.
List packages, newest first.
| Name | Type | | Description |
status query | string | optional | draft, sent, in_progress, completed, declined, expired, voided. |
q query | string | optional | Search title or signer. |
curl
curl 'https://app.gosignhere.com/api/v1/packages?status=completed' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/packages?status=completed', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages?status=completed', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages?status=completed', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages?status=completed');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"packages": [
{
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
]
}
}
GET /api/v1/packages/{id} #
API key or session.
One package: signers, documents, timeline and webhook deliveries.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
},
"events": [
{
"type": "package.sent",
"at": "2026-10-10T10:00:00Z"
}
],
"deliveries": []
}
}
}
POST /api/v1/packages/{id}/void #
API key or session.
Cancel a package in progress. Signers' links stop working.
| Name | Type | | Description |
reason | string | optional | Up to 500 characters; shown to signers. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/void' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"reason":"Terms changed"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'reason': 'Terms changed',
}
r = requests.post('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/void', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/void', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"reason": "Terms changed"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/void', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"reason": "Terms changed"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'reason' => 'Terms changed',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/void');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"status": "voided",
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
POST /api/v1/packages/{id}/signers/{sid}/resend #
API key or session.
Email a signer a fresh link (the old link stops working). Pass a new email to redirect it.
| Name | Type | | Description |
email | string | optional | A corrected address. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/resend' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"email":"ada@new.example.com"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'email': 'ada@new.example.com',
}
r = requests.post('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/resend', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/resend', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "ada@new.example.com"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/resend', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "ada@new.example.com"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'email' => 'ada@new.example.com',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/resend');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
PATCH /api/v1/packages/{id}/signers/{sid} #
API key or session.
Correct an unsigned signer's name or email.
| Name | Type | | Description |
name | string | optional | New name. |
email | string | optional | New address. |
curl
curl -X PATCH 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"name":"Ada King"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'name': 'Ada King',
}
r = requests.patch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Ada King"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Ada King"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'name' => 'Ada King',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
POST /api/v1/packages/{id}/signers/{sid}/edit #
API key or session.
Same as PATCH on the signer, for clients that cannot send PATCH.
| Name | Type | | Description |
name | string | optional | New name. |
email | string | optional | New address. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/edit' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"name":"Ada King"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'name': 'Ada King',
}
r = requests.post('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/edit', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/edit', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Ada King"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/edit', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Ada King"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'name' => 'Ada King',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/signers/018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f/edit');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
GET /api/v1/packages/{id}/verify #
API key or session.
Check the package's hash chain. Pass hash= (the SHA-256 of a PDF you hold) to learn whether that exact file is the signed one.
| Name | Type | | Description |
hash query | string | optional | SHA-256 of your copy, 64 hex characters. |
curl
curl 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify?hash=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify?hash=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify?hash=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify?hash=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/verify?hash=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"ok": true,
"found": true,
"state": "consistent",
"status": "completed",
"pre_match": true,
"post_match": true,
"pdf_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"given_matches": true,
"verify_url": "https://app.gosignhere.com/verify/3f6c1c52-8b0e-4c1a-9a53-0d2f6c1b7e10"
}
}
GET /api/v1/packages/{id}/completed.pdf #
API key or session.
The signed PDF with its certificate page. Only after completion.
No request fields.
curl
curl -o out.pdf 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/completed.pdf' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/completed.pdf', headers=headers)
r.raise_for_status()
open('out.pdf', 'wb').write(r.content)
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/completed.pdf', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
const file = await res.blob(); // save or display it
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/completed.pdf', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
require('node:fs').writeFileSync('out.pdf', Buffer.from(await res.arrayBuffer()));
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/completed.pdf');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
file_put_contents('out.pdf', $out);
Response 200
The file itself (application/pdf), not JSON.
PATCH /api/v1/packages/{id} #
API key or session.
Edit a draft: title, message, expiry, signing_mode, documents or signers.
| Name | Type | | Description |
title | string | optional | New title. |
message | string | optional | New message. |
expires_in_days | integer | optional | 0 to 365. |
signing_mode | string | optional | sequential or parallel. |
signers | array | optional | The full signer list. |
curl
curl -X PATCH 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"title":"Services agreement v2"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'title': 'Services agreement v2',
}
r = requests.patch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Services agreement v2"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "Services agreement v2"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'title' => 'Services agreement v2',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
DELETE /api/v1/packages/{id} #
API key or session.
Delete a draft package.
No request fields.
curl
curl -X DELETE 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.delete('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"deleted": true
}
}
POST /api/v1/packages/{id}/documents #
API key or session.
Add a document to a draft.
| Name | Type | | Description |
document_id | uuid | required | A ready document. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"document_id":"018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f"}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'document_id': '018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f',
}
r = requests.post('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"document_id": "018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"document_id": "018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f"
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'document_id' => '018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f',
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
DELETE /api/v1/packages/{id}/documents/{docId} #
API key or session.
Remove a document from a draft.
No request fields.
curl
curl -X DELETE 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.delete('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/documents/018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
POST /api/v1/packages/{id}/reorder #
API key or session.
Set the document order of a draft.
| Name | Type | | Description |
order | array | required | Every document id once. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/reorder' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"order":["018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f","018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f"]}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'order': [
'018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f',
'018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f',
],
}
r = requests.post('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/reorder', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/reorder', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"order": [
"018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f",
"018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f"
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/reorder', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"order": [
"018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f",
"018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f"
]
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'order' => [
'018f6c1e-7b2c-7c4d-8e3f-2a3b4c5d6e7f',
'018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f',
],
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/reorder');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
GET /api/v1/packages/{id}/validate #
API key or session.
Check a draft is ready to send; lists what is missing.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/validate' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/validate', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/validate', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/validate', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/validate');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"ok": true,
"messages": []
}
}
GET /api/v1/packages/{id}/flow-preview #
API key or session.
Who receives the package, in which order.
No request fields.
curl
curl 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/flow-preview' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/flow-preview', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/flow-preview', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/flow-preview', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/flow-preview');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"steps": [
{
"sequence": 1,
"signers": [
{
"name": "Ada Lovelace",
"kind": "signer"
}
]
}
]
}
}
POST /api/v1/packages/{id}/send #
API key or session.
Send a draft. Emails go to the first signer(s).
| Name | Type | | Description |
prefill | object | optional | Values for prefilled fields, keyed by field_key. |
curl
curl -X POST 'https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/send' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"prefill":{}}'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
payload = {
'prefill': {},
}
r = requests.post('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/send', headers=headers, json=payload)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/send', {
method: 'POST',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"prefill": {}
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/send', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"prefill": {}
}),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$payload = [
'prefill' => (object) [],
];
$ch = curl_init('https://app.gosignhere.com/api/v1/packages/018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f/send');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"package": {
"id": "018f6c1e-7b2a-7c4d-9e3f-0a1b2c3d4e5f",
"status": "sent",
"title": "Services agreement",
"message": "Please sign by Friday.",
"expires_in_days": 30,
"expires_at": "2026-11-09T10:00:00Z",
"signing_mode": "sequential",
"created_at": "2026-10-10T10:00:00Z",
"document_count": 1,
"page_count": 3,
"documents": [
{
"document_id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"page_count": 3
}
],
"signers": [
{
"id": "018f6c1e-7b2d-7c4d-8e3f-3a4b5c6d7e8f",
"slot": 1,
"role": "R1",
"kind": "signer",
"name": "Ada Lovelace",
"email": "ada@example.com",
"sequence": 1,
"status": "pending",
"approval": false
}
],
"validation": {
"ok": true,
"messages": []
}
}
}
}
Templates
GET /api/v1/templates #
API key or session.
Your templates.
| Name | Type | | Description |
q query | string | optional | Search the title. |
curl
curl 'https://app.gosignhere.com/api/v1/templates' \
-H 'Authorization: Bearer gsh_live_YOUR_KEY'
Python
import requests
headers = {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
}
r = requests.get('https://app.gosignhere.com/api/v1/templates', headers=headers)
r.raise_for_status()
print(r.json())
JavaScript
// Call this from your server. A live key in browser code is a leaked key.
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/templates', {
method: 'GET',
headers: {
'Authorization': 'Bearer gsh_live_YOUR_KEY',
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
Node.js
async function main() {
const res = await fetch('https://app.gosignhere.com/api/v1/templates', {
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.GSH_API_KEY}`,
},
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.json());
}
main();
PHP
<?php
$ch = curl_init('https://app.gosignhere.com/api/v1/templates');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . 'Bearer ' . getenv('GSH_API_KEY'),
],
]);
$out = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $out; // HTTP $status, body {"data": ...}
Response 200
{
"data": {
"documents": [
{
"is_template": true,
"id": "018f6c1e-7b2b-7c4d-8e3f-1a2b3c4d5e6f",
"title": "Services agreement",
"folder_id": "018f6c1e-7b2e-7c4d-8e3f-4a5b6c7d8e9f",
"folder_name": "Contracts",
"status": "ready",
"kind": "upload",
"created_by": "018f6c1e-7b30-7c4d-8e3f-6a7b8c9daebf",
"created_by_name": "Grace Hopper",
"created_at": "2026-10-10T09:30:00Z",
"updated_at": "2026-10-10T09:31:00Z",
"tags": [],
"render_status": "ready",
"render_error": null,
"page_count": 3,
"source_name": "agreement.pdf",
"source_bytes": 184320
}
]
}
}