DocBloc Logo
  • Home
  • Releases
  • Pricing
  • Contact

Loading...

Integrating

  • Overview
  • Quickstart
  • Headless
  • Redirect
  • Iframe embed
  • Native component

Quickstart

Everything below is copy-pasteable and gets you from zero to a signed, verified document. It is deliberately self-contained — the linked pages go deeper on any one step, but you should not need them to get something working.

Keep your own copy of signed documents

DocBloc deletes a submission and its signed file 30 days after the submission's expiry window elapses — not 30 days after signing. A submission with a 14 day signing window is removed 44 days after it was created, whether it was signed on day one or day fourteen.

If you need the document for longer, retrieve and store it yourself when submission.completed arrives. That event carries everything needed to fetch it.

1. Create an application

In DocBloc, under DocBloc API, create an application. You get a client id, a client secret and a webhook secret — shown once. DocBloc stores only a hash of the client secret, so losing it means rotating it, which stops the old one working immediately.

On the same screen, set whichever of these your integration needs:

  • Webhook URL — leave empty and no events are ever delivered.
  • Allowed redirect URLs — only for the redirect mode.
  • Allowed embed origins — only for framing a DocBloc page (sign page or field configurator) inside your own. Scheme and host, no path.

2. Exchange your credentials for a token

POST /auth
Content-Type: application/json

{ "clientId": "...", "clientSecret": "..." }

200 OK
{ "data": { "accessToken": "eyJ...", "expiresOn": "2026-09-21T12:34:56Z" } }

Tokens last 90 minutes. Cache and reuse one rather than exchanging per request — POST /auth is rate limited. DocBloc.Client (.NET) and @docbloc/client (server-side Node) do this caching for you, so everything after this step assumes one of those.

3. Create a template

A template is a PDF plus the fields that go on it. There are two ways to get one, and most integrations only ever need the first:

A. You already know where the fields go. Upload the PDF and describe every field in the same call — no configurator, no coordinate arithmetic if you use anchorText instead of raw x/y:

POST /pdfadmin/template
Content-Type: multipart/form-data

file: agreement.pdf
request: {
  "name": "Supplier agreement",
  "fields": [
    {
      "name": "signature",
      "type": "Signature",
      "recipientIndex": 1,
      "anchorText": "{{signature_1}}",
      "anchorOffsetY": -10,
      "width": 180,
      "height": 40
    },
    {
      "name": "signed_date",
      "type": "Date",
      "recipientIndex": 1,
      "anchorText": "{{date_1}}",
      "width": 100,
      "height": 20
    }
  ]
}

anchorText finds that exact text in the PDF and positions the field relative to it — the text must appear exactly once. Without an anchor, position with pageNumber/x/y instead, in PDF points with the origin at the bottom-left of the page. A template needs at least one field, or submissions built from it have nothing to route to a recipient and fail outright.

B. You want a person to place the fields visually — your own admin laying out a template they just uploaded, with no DocBloc login. Upload the plain PDF, mint a configure link for it, and frame the configurator:

POST /pdfadmin
Content-Type: multipart/form-data
file: agreement.pdf
pdfName: Supplier agreement

200 OK
{ "data": { "id": "3f2b...", ... } }

POST /pdfadmin/3f2b.../configure-link
Content-Type: application/json
{ "expiryInMinutes": 60 }

200 OK
{ "data": { "token": "eyJ...", "url": "https://sign-docbloc.com/configure/eyJ..." } }

Frame url (or hand token to DocBlocConfigurator — see Iframe embed). The person placing fields needs no DocBloc account at all; the token itself is what authorizes them, scoped to this one template until it expires.

4. Create a submission

var submission = await docBloc.SubmissionAsync(templateId, new CreateSubmissionDTO
{
    ExpiryInMinutes = 60 * 24 * 14,
    Emails = new Dictionary<int, string> { [1] = signer.Email },
    ExternalReference = $"order-{order.Id}",
    Metadata = new Dictionary<string, string> { ["branch"] = branch.Name },
    FieldValues = new Dictionary<string, string>
    {
        ["signed_date"] = DateTime.UtcNow.ToString("dd/MM/yyyy"),
    },
});

externalReference is how you find this submission again without storing a mapping table — it comes back on every read and every webhook. Pass an Idempotency-Key header so a retried call returns the original submission instead of creating a second one and emailing the signer twice.

5. Get the signer to the document

Pick one, based on how much of the experience you want to own:

  • Do nothing. DocBloc has already emailed the signer a link. This is headless mode — the default, and the least that can go wrong.
  • Send them yourself. Read submission.Data.Workflow for recipient 1's Link and redirect them to it — see Redirect.
  • Frame it in your own page:
    import { DocBlocSignature } from '@docbloc/embed'
    
    <DocBlocSignature
        baseUrl="https://sign-docbloc.com"
        token={signLink}
        style={{ height: '80vh' }}
        onCompleted={() => refreshTheRecord()}
    />
    Full write-up, events and the no-dependency version at Iframe embed.

6. Handle the webhook

[HttpPost("webhook")]
[AllowAnonymous]
public async Task<IActionResult> Receive()
{
    using MemoryStream buffer = new();
    await Request.Body.CopyToAsync(buffer);
    byte[] rawBody = buffer.ToArray();

    if (!_verifier.IsValid(rawBody,
            Request.Headers[DocBlocWebhookVerifier.SignatureHeader],
            Request.Headers[DocBlocWebhookVerifier.TimestampHeader]))
    {
        return Unauthorized();
    }

    var e = JsonSerializer.Deserialize<DocBlocEvent>(rawBody);

    if (e?.Type == "submission.completed" && await _processed.MarkIfNew(e.SubmissionId, e.Type))
    {
        var signed = await docBloc.SignedAsync(e.ExternalReference);
        await _files.Store(signed.Stream, $"{e.ExternalReference}.pdf");
    }

    return Ok();
}

Four rules, all of which matter and are covered in depth on the overview and headless pages:

  • Verify the raw request body — a round trip through a JSON parser will not verify.
  • Check the timestamp against a tolerance, so a captured delivery can't be replayed.
  • Be idempotent — a retried delivery must not advance your record twice.
  • Answer fast; do the slow work (fetching the signed PDF) behind the response.

Where to go next

  • Headless — the full write-up of step 5's first option.
  • Redirect — sending the signer yourself, and what to trust (and not trust) on their return.
  • Iframe embed — framing the sign page or the field configurator, with or without @docbloc/embed.

DocBloc

Secure, simple, and compliant e-signatures for modern businesses.

Product

  • Features
  • Pricing

Resources

  • Release Notes
  • API Docs

© 2026 DocBloc. All rights reserved.

PrivacyTerms