Oktul home
  • English
  • Estonian

The documentation is in English only.

Contact us

Automation and webhooks

Starting a SignPlus signing or exporting a PDF from an automation rule, and the two webhooks SignPlus sends when a signing completes or a page is edited.

Starting a signing from a Jira automation rule, no sound.
What the video shows
  1. The title: Start a signing from Jira.
  2. In a Jira automation rule, add an action, search for signplus and choose Start a SignPlus signing under Other apps.
  3. The first time, select Connect. A flag says the connection is created.
  4. Choose the Legal space, type part of the page title and pick Service agreement.
  5. Under Signers, select Mari Tamm and select Add signer.
  6. Select Save and enable. The rule reads Enabled.
  7. Oktul, Atlassian Marketplace Partner.

A rule can start a signing, export a PDF, and react when a signing completes or a signed page changes.

Which product, and what that changes

The SignPlus actions appear in Jira automation, where Atlassian publishes the module. Typical use: a work item moves to Approved and its Confluence page goes out for signature.

In Confluence, use Send web request with the REST API, on any plan.

You want to In Jira In Confluence In Code Studio
Start a signing The SignPlus component Send web request http.post to the REST API
Export a PDF The SignPlus component Send web request http.post to the REST API
React when a signing completes Incoming webhook trigger Incoming webhook trigger An API trigger
React when a signed page is edited Incoming webhook trigger Incoming webhook trigger An API trigger

The Jira components need SignPlus connected to Jira. See connecting Jira.

What a rule acts as

SignPlus itself. Page history and logs name SignPlus, not a person. Page restrictions apply to the app like anyone else. A rule acts only in the spaces a Confluence administrator names under Spaces automation rules can use in the global settings. With none named, every rule stops and says why.

Add SignPlus to a Jira flow

In the Jira flow builder, add an action and pick Start a SignPlus signing or Export a page as PDF (under Other apps).

  1. Connect it, once

    The first time, select Connect. Connection created confirms it.

  2. Choose the page

    Pick the Space, then type part of the page title.

  3. Fill in the rest

    Empty fields follow the space’s settings.

  4. Save the flow

    Use Save and enable in the flow builder.

Choosing the page

Use the pickers for a fixed page, such as a policy. To take the page from the work item, turn on Enter a page ID or smart value instead, for example {{issue.customfield_10050}}.

Start a signing from a flow

Section What it holds
Page The page, picked or given as an id or smart value
Signers Everyone invited when the flow runs
Document Document name, Format and Message to signers. An empty name uses the page title
Deadline When the signing should be finished, if at all
Page access while it is signed Make the page read-only, Restrict page viewing to signers and viewers, Include attachments. The space may overrule each

Signers

Choose Who to add (Internal user, External partner or Group), the Role, then Add signer.

For signers known only at run time, turn on More signers from smart values: comma-separated addresses, Name <address>, and [viewer] for a viewer. For example {{issue.reporter.displayName}} <{{issue.reporter.emailAddress}}>.

Deadline

Pick a date and time, or select Advanced for a smart value, such as a week from now:

{{now.plusDays(7).format("yyyy-MM-dd'T'HH:mmXXX")}}

It must include an offset, such as 2026-12-31T17:00+02:00, and be in the future. Empty leaves it to the space.

What later steps can read

Smart values this action returns, at the foot of the step, lists them:

{{triggeredConfluenceSigning.reference}} the signing reference
{{triggeredConfluenceSigning.status}} "pending", or "queued" for a large signing
{{triggeredConfluenceSigning.signerCount}} how many people were asked
{{triggeredConfluenceSigning.documentName}} the name the document was given
{{triggeredConfluenceSigning.documentUrl}} the document that was SENT for signing
{{triggeredConfluenceSigning.documentBase64}} the same, as base64, up to 4MB
{{triggeredConfluenceSigning.documentDigest}} its SHA-256, as given to Dokobit

documentUrl is not signed yet. It is the sent-for-signing-….pdf attached to the page. For the signed file, use the completion webhook.

A group or more than 100 people runs in the background: status is queued and the reference and document fields are empty until the completion webhook.

The same from Confluence

Add Send web request:

Field Value
Web request URL <your SignPlus address>/v1/signings
Method POST
Headers Authorization: Bearer <token> and Content-Type: application/json
Body Custom data, below
Wait for response Ticked
{
"pageId": "{{page.id}}",
"signers": [
{ "email": "{{initiator.email}}", "name": "{{initiator.displayName}}" }
],
"name": "{{page.title}}"
}

Later steps read {{webhookResponse.status}} (202) and {{webhookResponse.body.jobId}}. The reference arrives with the completion webhook or from GET /v1/pages/{pageId}/signing-jobs/{jobId}. For the address and token, see REST API.

Tick Wait for response

Without it, webhookResponse is empty. Tokens expire after an hour, so fetch a fresh one first.

Export a PDF from a flow

Export a page as PDF renders the page with its space’s styling and attaches it. It takes the page, a Document name (default: the page title) and Include attachments (see attachments). Later steps can read:

{{createdConfluencePdf.downloadUrl}} where it is attached in Confluence
{{createdConfluencePdf.attachmentName}} the filename
{{createdConfluencePdf.sizeBytes}} how big it is
{{createdConfluencePdf.contentBase64}} the bytes, up to 4MB, empty above that

From Confluence, send a POST to <your SignPlus address>/v1/pages/{{page.id}}/pdf?inline=true with the same headers and {"name":"{{page.title}}"} as the body, and read {{webhookResponse.body.downloadUrl}}.

Prefer the URL to contentBase64. The base64 is the whole document, and it stays in the audit log. The URL needs the recipient’s own Confluence access.

Webhooks

Set both on Webhooks in the global settings. They work the same with Jira and Confluence.

When a signing completes

Sent once the signed file is attached, and carries it.

  1. In Jira or Confluence, create a rule with an Incoming webhook trigger. Atlassian gives you a URL and a secret.
  2. Add the actions you want, then publish the rule. An unpublished rule receives nothing.
  3. In SignPlus, open Webhooks, then When a signing completes. Turn on Send this notification and paste the URL under Address.
  4. Add a header named X-Automation-Webhook-Token with the secret as its value.
  5. Leave Include the signed document as base64 on, unless you only want the link.
  6. Save, and approve the address in the dialog Atlassian shows.

Add an address adds receivers, up to 10, each with its own headers and base64 switch.

The rule then receives:

{
"event": "signing-completed",
"pageId": "123456",
"pageTitle": "Supplier terms",
"pageUrl": "https://your-site.atlassian.net/wiki/spaces/.../pages/123456",
"spaceName": "Legal",
"reference": "a3f9c2d1...",
"documentName": "Supplier agreement.pdf",
"documentUrl": "https://your-site.atlassian.net/wiki/download/attachments/123456/Supplier%20agreement.pdf?version=1&api=v2",
"documentBase64": "JVBERi0xLjcK...",
"sizeBytes": 184320,
"signedVersion": 7,
"completedAt": "2026-09-19T09:24:00.000Z",
"progress": { "total": 1, "required": 1, "signed": 1, "declined": 0 },
"signers": [
{ "name": "Anna Tamm", "status": "signed", "signedAt": "2026-09-19T09:20:00.000Z" }
],
"signersTruncated": false
}
  • Sent once per signing. signers lists the first 500; past that signersTruncated is true, and the REST API lists the rest.
  • No email addresses. But the signed document holds each certificate, and an Estonian one includes the personal code. Turn base64 off for receivers that should not hold it.
  • Above 4MB, documentBase64 is null; the URL remains.

Receive it in Code Studio or a Forge app

An Oktul Code Studio API trigger runs a script with the webhook’s JSON as its event, so the script reads event.reference and event.documentUrl directly.

  1. In Code Studio, open API triggers and create one for the script below. Copy its address and its secret. For a Forge app, declare a web trigger, deploy, and forge webtrigger prints its address; choose a secret and store it with forge variables set --encrypt SIGNPLUS_WEBHOOK_SECRET <secret>.
  2. In SignPlus, open Webhooks, then When a signing completes, and paste the address under Address.
  3. Add a header named Authorization with the value Bearer followed by the secret.
  4. Save, and approve the address in Atlassian’s dialog.

The curl tab sends a test notification to the receiver before SignPlus sends a real one.

interface SigningCompleted {
event: 'signing-completed';
pageId: string;
reference: string;
documentName: string;
documentUrl: string;
completedAt: string;
progress: { total: number; signed: number };
}
export default async function (event: SigningCompleted) {
if (event.event !== 'signing-completed') return { statusCode: 204 };
await store.set(`signed:${event.pageId}`, {
reference: event.reference,
documentUrl: event.documentUrl,
completedAt: event.completedAt,
});
log.info(`${event.documentName}: ${event.progress.signed} of ${event.progress.total} signed`);
return { statusCode: 204 };
}
import { timingSafeEqual } from 'node:crypto';
const expected = Buffer.from(`Bearer ${process.env.SIGNPLUS_WEBHOOK_SECRET}`);
export async function receive(request) {
const given = Buffer.from(request.headers.authorization?.[0] ?? '');
if (given.length !== expected.length || !timingSafeEqual(given, expected)) {
return { statusCode: 401, headers: {}, body: '' };
}
const notice = JSON.parse(request.body);
if (notice.event === 'signing-completed') {
console.log(`Signing ${notice.reference}: ${notice.progress.signed} of ${notice.progress.total} signed`);
}
return { statusCode: 204, headers: {}, body: '' };
}
curl -X POST "$RECEIVER_URL" \
-H "Authorization: Bearer $RECEIVER_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "signing-completed",
"pageId": "123456",
"reference": "a3f9c2d1e4b5a6978877665544332211",
"documentName": "Supplier agreement.pdf",
"documentUrl": "https://your-site.atlassian.net/wiki/download/attachments/123456/Supplier%20agreement.pdf",
"completedAt": "2026-09-19T09:24:00.000Z",
"progress": { "total": 1, "required": 1, "signed": 1, "declined": 0 }
}'

The script keeps the signed document’s link per page in Code Studio’s store, where another script reads it with store.get('signed:123456'). Turn Include the signed document as base64 off for a Code Studio receiver: an API trigger refuses a request over 200 KB, and the link is enough to fetch the document.

When a signed page is edited

Set up the same way under When a signed page is edited:

{
"event": "signed-page-modified",
"pageId": "123456",
"pageTitle": "Supplier terms",
"pageUrl": "https://your-site.atlassian.net/wiki/spaces/.../pages/123456",
"spaceName": "Legal",
"reference": "a3f9c2d1...",
"signingStatus": "completed",
"signedVersion": 7,
"currentVersion": 8,
"modifiedAt": "2026-09-19T11:02:00.000Z"
}

Identifiers and versions only. A useful rule notifies the space owner and starts a fresh signing.

Why Atlassian asks you to approve the address

A Forge app can only reach hosts it declares, so Atlassian asks your administrator to approve each webhook host. Cancel, and nothing is saved. Withdraw approval later in Atlassian Administration.

When something does not work

What you see Usually
The SignPlus action is not in the Confluence rule builder Expected. The components are Jira’s; use Send web request in Confluence
The SignPlus action is not in the Jira flow builder either SignPlus is not connected to Jira yet. See connecting Jira
The step asks to connect Select Connect. Atlassian asks before SignPlus can be used in a flow for the first time
The Page picker lists nothing You cannot see any page in that space, or nothing matches what you typed. Turn on Enter a page ID or smart value instead to give the id
The rule runs and nothing happens Wait for response is not ticked, or the rule is not published
SignPlus cannot add attachments to that page or SignPlus is not allowed to edit this page in the rule’s audit log SignPlus cannot edit that page. Check the page restrictions
401 from a web request The token has expired. They last an hour
400 about a format, a message or a deadline The space’s SignPlus settings forbid what the rule asked for
The webhook never arrives The address was not approved in Atlassian’s dialog, or the receiving rule is not published
{{webhookData.documentBase64}} is empty The document is over 4MB, or Include the signed document as base64 is off
The signed document is watermarked The site is in test mode. See signing mode

The rule’s audit log shows each step. SignPlus’s side is on Logs in the global settings.

What a rule cannot do

  • Sign on somebody’s behalf. A rule sends the request; only the signer can sign.
  • Get a signed document when a signing starts. There is nothing signed yet.
  • Reach a page SignPlus itself cannot.
  • Overrule the space’s settings. A rule is checked against them every time.

A problem or a question? Write to support@oktul.com or open a request in the Help Center (opens in a new tab).