Skip to content

Signing API

The signing API lets your systems have a person sign PDF documents, with a legally recognized digital signature, from inside your own app. The person does not need the ePahichan app, and does not need to hold a certificate already: if they have none, one is issued for them at the moment they accept.

A bank uses it for loan documents: the loan system sends the agreement, the customer taps Accept in the bank’s app and types the code sent to their phone, and the bank receives the signed agreement and the signed certificate application. Nothing in the API is specific to loans, so the same calls serve account opening, insurance, leases, employment contracts or anything else a person signs.

  1. Your server uploads the documents (POST /v1/files) and creates a signing request (POST /v1/signing-requests) naming the signer by name, phone number and identity document, and saying where each signature goes.
  2. Your app shows the request to the signer: who is asking, and each document. It uses your publishable key and the request’s client_secret.
  3. The signer accepts. A 6-digit code goes to their phone. They type it in your app.
  4. Everything is signed at once. If the signer holds no certificate, their key is made and kept by ePahichan and their certificate is issued, both on the spot. Then each document is signed, the certificate application first.
  5. Your server receives the signed PDFs, through a webhook (signing_request.completed) and the documents’ content_url.

Afterwards the signer can sign in to the ePahichan app with the same phone number and finds their certificate there.

The code is sent by ePahichan to the signer’s phone, and your systems never see it before the signer types it. It is what shows that the signer, not the organization asking, accepted the documents. The request records when it was sent, how many tries it took and when it was verified, and your organization receives that record with the request.

A person who holds no certificate yet must be sent their certificate application form (Schedule 5) in the same request, as a document with "purpose": "certificate_application", together with their identity document details. It is always signed first: a new certificate stays on hold until its application form is signed, and a signature made during the hold would not be valid.

To set up someone’s digital signature without any other document, send a request with the application form alone.

A person is issued one certificate. Its key is kept for them in ePahichan’s HSM, and every later request to the same phone number is signed with it, with no application form. To know which case you are in before you build the request, look the signer up from your server with their phone and identity document number:

Terminal window
curl $EPAHICHAN_API/v1/signers/lookup \
-H "Authorization: Bearer $EPAHICHAN_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"phone": "+9779861605307", "identity_number": "27-01-75-01234"}'
# {"object": "signer_lookup", "certified": true,
# "certificate": {"serial_number": "…", "not_after": "…", "expired": false, "key_custody": "hsm", …}, …}

With @epahichan/sdk: await epahichan.signers.lookup({ phone, identityNumber }).

  • certified: false: include the certificate application (Schedule 5).
  • certified: true: leave it out. The request is refused with signer_already_certified if you include it.

Both values are required, and the answer is certified only when the phone and the document number are both the holder’s; any other pair reads as not certified, so a phone number alone reveals nothing. If the phone holds a certificate under a different document, the signing request itself is refused with signer_identity_mismatch. The phone goes in the body so it stays out of URLs and logs. Only a secret key can look signers up.

Test mode Live mode
Keys sk_test_…, pk_test_… sk_live_…, pk_live_…
Where Your sandbox organization Your production organization, after going live
Codes Never sent; always 424242 Sent by SMS
Certificates Issued by a test authority, never valid Issued by Radiant InfoTech Nepal, the licensed certifying authority

The secret key is for your server. The publishable key is for your app: it can only take the signer’s steps, and only for a request whose client_secret it holds. Manage both under API keys in the console.