Skip to content

REST API

The REST API does what the panel on the page does, from another system: a contract tool, a workflow engine, an HR system or a script. It is about signing only, and it is not a general Confluence API.

The global settings carry the same reference under API access, beside the one thing no website can tell you: your site’s own address.

Before you start

You need three things:

  1. SignPlus installed on your Confluence site.
  2. The API address. API access, then API address. Atlassian creates it for each installation, so it is different on every site and cannot be guessed. Every endpoint below is a path added to it, such as /v1/signings.
  3. An Atlassian service account with an OAuth 2.0 credential. SignPlus issues no API keys of its own. An organisation administrator creates the service account and its credential in Atlassian Administration, copies the client_id and client_secret, which are shown once, grants the credential one scope, read:confluence-user, and gives the service account the Confluence permissions it should have. Atlassian’s instructions.

What the service account’s permissions decide

SignPlus spends the token once against your site to find out whose it is, checks that account’s Confluence permissions on the page on every request, and reads the page as that account. More scopes on the credential grant nothing extra.

To The account needs
Read a page’s status, its signings, their people, a PDF or a signed document View the page
Start a signing, cancel one, or export a PDF Edit the page
Delete a finished signing What the site’s deleting signings setting allows

Because the page is read as the service account, a signing holds what that account sees: a Jira work items table lists what it may see, and an excerpt from a page it cannot open is left out. Give it the access the document should reflect. A token from another Atlassian organisation is refused by Atlassian itself.

Your first signing

Fetch a token. The client id and secret travel in the body of a POST, read from the environment so the secret is never written on a command line.

Terminal window
export SIGNPLUS_URL="https://513c7988-....hello.atlassian.net/x1/G7gth8r-Vw5-wMfGB7FGgW6AQ9A"
export CLIENT_ID=... CLIENT_SECRET=...
export SIGNPLUS_TOKEN=$(jq -n '{grant_type: "client_credentials", client_id: env.CLIENT_ID, client_secret: env.CLIENT_SECRET}' \
| curl -s -X POST 'https://auth.atlassian.com/oauth/token' \
-H 'Content-Type: application/json' --data @- \
| jq -r .access_token)

The token lasts 60 minutes. A page id is in the page’s address, or under Page information.

1. Ask where the page stands

Terminal window
curl -s "$SIGNPLUS_URL/v1/pages/123456/status" -H "Authorization: Bearer $SIGNPLUS_TOKEN"
{ "pageId": "123456", "spaceId": "98765", "pageVersion": 4, "state": "ready-to-sign", "signings": [] }

A 401 means the token is wrong or has expired. A 403 means the service account cannot see that page.

2. Start a signing

Terminal window
curl -s -X POST "$SIGNPLUS_URL/v1/signings" \
-H "Authorization: Bearer $SIGNPLUS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"pageId": "123456",
"signers": [
{ "email": "anna@example.com", "name": "Anna Tamm" },
{ "group": "finance-team" }
]
}'
{ "jobId": "7c1e9a0f3b2d4c5e6f7a8b9c", "status": "queued", "pageId": "123456",
"statusUrl": "/v1/pages/123456/signing-jobs/7c1e9a0f3b2d4c5e6f7a8b9c" }

The answer is 202 Accepted. The request has been checked against the space’s settings, and the signing is prepared in the background: the page is rendered, every member of the group is looked up, and everybody is sent to Dokobit. That takes seconds for a few people and minutes for a group of thousands.

3. Follow the job

Terminal window
curl -s "$SIGNPLUS_URL/v1/pages/123456/signing-jobs/7c1e9a0f3b2d4c5e6f7a8b9c" \
-H "Authorization: Bearer $SIGNPLUS_TOKEN"
{ "id": "7c1e9a0f3b2d4c5e6f7a8b9c", "status": "started", "reference": "a3f9c2d1...", "documentName": "Expense policy" }

queued and running mean it is being prepared. started means Dokobit has it and the invitations are out; keep the reference, which is the signing’s public id and what the other endpoints take. failed carries the reason in message.

4. See who has not signed

Terminal window
curl -s "$SIGNPLUS_URL/v1/signings/a3f9c2d1.../signers?pageId=123456&status=pending" \
-H "Authorization: Bearer $SIGNPLUS_TOKEN" | jq -r '.signers[] | [.name, .email] | @tsv'

Do not poll for completion

A signing takes minutes or days. Configure the completion webhook instead, and SignPlus posts you the signed document when it exists.

Authentication and limits

Authorization: Bearer <the access token>

That is the only credential. Every authentication failure answers the same 401 with the same sentence, so the API cannot be used to find out which tokens are live. Basic authentication is not supported. Revoke the credential in Atlassian Administration, and SignPlus stops accepting its tokens within two minutes.

Limit
Rate 60 requests per minute per account, answered with 429
Request body 2MB, answered with 413
People on one signing 25,000, after groups are expanded
People named one by one in a view restriction 200. A group counts as one
People on one reply 100 by default, any number with limit, and nextCursor reaches the rest
Document returned inline 4MB, above which contentBase64 is null rather than truncated
Time 55 seconds per request. A signing is queued, so it is not bound by this

Every request, a refused one included, is recorded under Logs in the global settings: what was called, the outcome and the account it acted as. Never the token.

Endpoints

Every reply is JSON, errors included. pageId is required on every endpoint that takes a reference, so a reference from one page cannot address a signing on another.

Endpoint Does Needs
POST /v1/signings Queues a signing. 202 and a job Edit
GET /v1/pages/{pageId}/signing-jobs/{jobId} How a queued signing went. Kept for 7 days The account that queued it
GET /v1/pages/{pageId}/status Where a page stands, and its signings, newest first View
GET /v1/signings/{reference}?pageId= One signing, with counts rather than its people View
GET /v1/signings/{reference}/signers?pageId= The people on a signing, a page at a time View
GET /v1/signings Signings on a page with ?pageId=, or every signing the account started View
DELETE /v1/signings/{reference}?pageId= Cancels a running signing, or deletes a finished one See above
POST /v1/pages/{pageId}/pdf Exports the page as PDF and attaches it Edit
GET /v1/pages/{pageId}/pdf/{attachmentId} A document SignPlus attached to the page View
GET /v1/signings/{reference}/document?pageId= The signed document, once everyone has signed View

POST /v1/signings

Field Required Notes
pageId yes The page to sign
signers yes At least one, below
name no What the document is called. The page title when left out, numbered when that name is already attached
type no pdf, asice, bdoc, edoc or adoc. The space decides which are allowed
message no Sent to signers. The space may require it or forbid it
deadline no ISO 8601 date and time with an offset, in the future
hardDeadline no Refuse signatures after the deadline. The space may overrule
lockPage no Make the page read-only while it is signed. The space may overrule
restrictViewers no Restrict viewing to the participants. The space may overrule
includeAttachments no Append the page’s attachments

A signer is a person or a group, with role signer (the default) or viewer:

{ "email": "anna@example.com", "name": "Anna Tamm", "role": "signer" }
{ "group": "finance-team", "role": "signer" }
{ "groupId": "0f6a1b2c-...", "role": "viewer" }
  • A person is named by email address. When the address belongs to a Confluence user who can view the page, they are added as that user. Anybody else signs as an external signer. Confluence cannot be searched by address, so the match is made by name and confirmed against the account’s own address.
  • A group is named by its name or its id, and every member is invited with the group’s role. A member Confluence gives no address for cannot be invited, and the job’s message says how many. Unlike the panel on the page, a service account is not limited to groups it belongs to: its Confluence permissions decide.
  • spaceId is not a field. SignPlus asks Confluence which space the page is in, so a caller cannot choose which space’s rules apply.

GET /v1/pages/{pageId}/status

state Means
ready-to-sign Nothing has been started on this page
pending-unmodified A signing is out and the page has not changed
pending-modified A signing is out and the page has changed since it was sent
signed-valid Signed, and the page is exactly what was signed
signed-modified Signed, and the page has been edited since
declined A signer refused
unknown The stored status is not one of the above

The newest signing decides the state, by the same hash the byline uses.

GET /v1/signings/{reference}/signers

Query Notes
limit People per reply, 100 by default
cursor The nextCursor of the previous reply
status pending, signed or declined
email, accountId Repeat either to ask about specific people. notFound lists anyone never asked

A reply can come back shorter than limit when reading more would outrun the request’s time. Only an absent nextCursor means you have everybody. This is the one place SignPlus returns a signer’s email address, to an account that can view the page, because chasing the people who have not signed needs it. The panel on the page never sends one to a browser.

DELETE /v1/signings/{reference}

A running signing is cancelled: removed from Dokobit for every signer, with its page restrictions lifted. A finished one is deleted: its record goes, and the signed file stays attached to the page. The same permissions apply as in the panel: see cancelling or deleting a signing. A 502 means Dokobit could not be reached or the page restrictions could not be put back; nothing was removed, and sending it again is safe.

The PDF endpoints

POST /v1/pages/{pageId}/pdf takes name, which the {documentName} placeholder prints, and includeAttachments. Add ?inline=true to have the bytes back as base64 beside the attachment’s full Confluence address. Without Confluence credentials, keep the attachmentId and fetch the file with GET /v1/pages/{pageId}/pdf/{attachmentId}.

GET /v1/signings/{reference}/document answers 409 with the signing’s state until every signer has signed and Dokobit has handed the file over.

Errors

Status Means
400 Something is missing, or the space’s rules refuse it. error says which
401 The token is not valid here. All reasons answer the same way
402 The site has no active SignPlus licence
403 The service account cannot reach that page, or may not do that to it
404 No such page, signing, job, document or path
409 The signing has no signed document yet
413 The body is over 2MB
429 Over 60 requests in a minute for this account
500 Something failed inside SignPlus. The detail is in the app’s logs, never in the reply
502 Dokobit refused, or could not be reached
503 Signing is not configured on this site, for example no Dokobit token
{ "error": "At least one signer is required in \"signers\"." }

What the API never returns

  • The Dokobit document token, which downloads the signed file and is what a signer signs with. The reference is its SHA-256 and cannot be reversed.
  • A signer’s Dokobit token, for the same reason.
  • A stored copy of the document. None is stored: a document comes back only from the PDF endpoints, which read it from the page.

Things that will catch you out

  • The address is per installation. A script that works on your sandbox has the wrong address for production.
  • The service account needs Confluence permissions, not only a credential. A new one can authenticate and then be refused 403 by every page.
  • A signing is queued. The POST answers before the signing exists. Follow the job, or the completion webhook, for the reference.
  • The space’s settings win. A refusal that mentions a format or a message points at the space’s SignPlus settings.
  • Test mode is watermarked. In Test signing mode, documents can only be signed with Dokobit’s test identities and have no legal effect.
  • Tokens expire after an hour. A script that caches one forever starts answering 401 exactly once, in production.

When you ask for help with a signing, quote its reference: it identifies the signing and reveals nothing about its contents.


A problem or a question? Write to support@oktul.com or open a request in the Help Center. Both reach the same service desk, so either way the request gets a reference and an SLA measuring the response.