MENU
Pdcflowlogo
PHP CSharp Perl Ruby
FlowApi

Flow Service API

Flow Service (previously called Signature Service) enables easy integration of sending requests for signatures, payments, documents, and image uploads. Integrators are also able to retrieve previously sent Flow requests and create transaction reports on previous requests. All requests are made through common HTTP POST, GET, PUT, PATCH requests.

Authentication will be done with a Base64 encoded username:password, passed in through the BASIC HTTP Authorization Header.

If the request cannot be delivered by the requested method (email or text message), the integrator will receive an HTTP error 500 with a RequestErrorList containing an ERR type RequestError. The request will thus be treated as a failed request and will not be stored for future reporting or retrieval.

Signature

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures

POST to the signature endpoint to send a request though email, text, or both.
GET to retrieve a previous signature.
PUT to modify a previous signature.

Attribute Description
signatureId
Numeric20
The id of the signature request.
firstName
Alphanumeric45
Required
The first name of your client.
lastName
Alphanumeric45
Required
The last name of your client.
emailAddress
Alphanumeric65
The email address to send the request to. Sending both emailAddress and mobileNumber will send the request to both.
mobileNumber
Numeric15
The phone number to send request to. Sending both emailAddress and mobileNumber will send the request to both.
Format: With country code

See the important note about SMS Opt In.
username
Alphanumeric65
Conditional
Username or email of the employee sending this request.
Constraint(s): Required for modification (PUT) requests.
description
Alphanumeric160
Conditional
Description of what the signature is for. Will show with the signature.
Constraint(s): Only required with standalone signature.
verificationPin
Numeric8
Required
Shared secret for client verification.
Constraint(s): Must be between 4 and 8 digits long or -1.
-1 will prevent the pin verification page from being displayed. ** Warning, this will allow anyone with the request url to complete the request. **
pinDescription
Alphanumeric50
Required
Description of the verificationPin.
verificationPageHeader
Alphanumeric160
Text that will be displayed above the verificationPin on the verification page.
pageFooter
Alphanumeric320
Text that will be displayed below the pinDescription on the verification page.
maxPinAttempts
Numeric2
Maximum amount of attempts the client is allowed for verification before transaction is locked.
Default: 3
requestGeolocation
Boolean5
Request the geolocation from the client.
Constraint(s): Client can refuse to share location, preventing capture.
Valid value(s): true, false
Default: true
latitude
NumericString25
Readonly
The latitude geolocation of your client. Provided if the original request had requestGeolocation true and the client Browser/OS settings allow location sharing.
longitude
NumericString25
Readonly
The longitude geolocation of your client. Provided if the original request had requestGeolocation true and the client Browser/OS settings allow location sharing.
timeoutMinutes
Numeric6
Number of minutes client has to complete the transaction before it expires.
Default: 2 if a payment is included, otherwise 3
redirectLink
URL65
A URL link to direct client to, after signature is complete.
customMessage
AlphaNumeric320
Free form text to display at the end of the transaction.
payment
PaymentN/A
Data for payment request.
Constraint(s): See object definition below.
document
DocumentN/A
Data for document presentation.
Constraint(s): Document must be uploaded through POST to Document endpoint, then resultant documentId specified here. See object definition below.
imageUploadList
Readonly
ImageUploadListN/A
A list of ImageUpload objects uploaded by your client.
Constraint(s): See object definition below.
imageUpload
ImageUploadN/A
Information for image upload.
Constraint(s): See object definition below.
companyOverride
CompanyOverrideN/A
Data for overriding company information.
Constraint(s): See object definition below.
standaloneSignatureRequested
Boolean5
Whether standalone signature is desired or not.
Valid value(s): true, false
Default: true
transactionOrigin
String3
The origin of the transaction request.
Valid value(s): EXT
flowTitle
String50
The title of the flow. If sending the request via sms, this will be visible in the message sent.
templateName
String50
The name of the template used for this request. Can be used to associate similar requests together.
completionDate
Date25
The date and time the full request was completed.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
signatureReceivedDate
Date25
The date and time the signature was stored on our system.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
signatureReceivedTimezone
Numeric5
The timezone in which the signature was signed.
Format: GMT Offset
signatureClosed
Boolean5
Whether or not a the transaction was closed. Either all parts of the transaction were completed or an error occurred.
Valid value(s): true, false
modificationCode
Alpha5
Required
The modification to make on the transaction.
Valid value(s): CLOSE
postbackUrl
URL500
A URL to POST completed signature data to.
Constraint(s): Must be SSL (HTTPS)
POSTed data may include:
signatureId, completionDate, errorCode, errorMessage
postbackAuthHeader
AlphaNumeric512
An optional Authorization Header that will be provided when we POST to the provided postbackUrl
customEmailBody
AlphaNumeric60,000
Conditional
Text to include in the email request, above the signature link. If this is part of the request, ONLY this text, the signature link, and the customEmailFooter will be sent to the emailAddress.
Constraint(s): Required if the customEmailFooter is also requested.
customEmailFooter
AlphaNumeric60,000
Text to include in the email request, below the signature link. If this is part of the request, ONLY the customEmailBody, the signature link, and this text will be sent to the emailAddress.
errorCode
Alpha3
Code if an error occurred with the signature. See errorMessage for possible values.
errorMessage
Alphanumeric160
An explanation message for the error that occurred.
Constraint(s): Will only show if an errorCode is present.
Valid values for an errorCode:
  • DEV - Device not compatible
  • DSP - Attached document was disputed
  • EMP - Signature image is empty
  • ERR - Error processing request
  • FIC - File upload cancelled
  • FIL - Failed to save signature
  • IMC - Image upload request denied
  • INV - Invalid request
  • LCK - Transaction already closed
  • MAN - Transaction has been closed
  • NFN - Signature not found
  • PIN - Pin verification failed
  • PMD - Permission denied
  • PPC - Payment portal canceled
  • SDS - Attached schedule was disputed
  • SAF - Schedule activation failed
  • SES - Session invalid. Log in and try again
  • TMO - Transaction request expired
  • USB - Unsupported browser. Please upgrade to a newer browser
roundTripNVPS
ListN/A
List of roundTripNVP objects. These are Name/Value pass-through values.
Constraint(s): Max of 10 roundTripNVP objects per request. See object definition below.
pageOrder
List-AlphaN/A
A list of page enum values to define the order in which the receiver will view the pages of the request.
Constraint(s): Only pages for requested functionality can be included.
PG_PAY & PG_PMT can’t be included in the same request.
Valid value(s): PG_DOC, PG_IMG, PG_SIG, PG_PAY, PG_PMT, PG_RBD, PG_FIL
Default: PG_DOC, PG_IMG, PG_FIL, PG_SIG, PG_PAY
requestedDate
Date25
Date and time the transaction was requested.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
expirationDate
Date25
Date and time the transaction will expire. Based on the requestedDate and timeoutMinutes.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
signatureImage
Base64N/A
Base64 encoded signature image in .png format.
textSuccessful
Boolean5
Whether the text was successfully sent to the client.
Valid value(s): true, false
emailSuccessful
Boolean5
Whether the email was successfully sent to the client.
Valid value(s): true, false
signatureUrl
Alphanumeric160
The URL sent to the recipient to complete the signature request.
status
Alpha9
The current status of the request. For requests sent prior to June 2019, this field may be empty.
Valid value(s):
PENDING - The request has been sent.
OPEN - A valid PIN has been entered on the request, but the request has not been completed.
COMPLETED - The request has been successfully completed.
FAILED - The request has failed. This can be due to the document being denied, the request being manually closed, etc. An errorCode and errorMessage will provide the reason for the failure.
EXPIRED - The request has exceeded the timeoutMinutes and cannot be completed.
statusDate
Date25
The date that the current status happened. For an EXPIRED status, this will be the date the request expired. For requests sent prior to June 2019, this field may be empty.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
componentList
ListN/A
List of related Component objects. See object definition below.
emailNotificationIdList
ListN/A
List of related email Notification Ids. READONLY
emailAttemptList
ListN/A
List of related EmailAttempt objects. See object definition below. READONLY
smsNotificationIdList
ListN/A
List of related SMS Notification Ids. READONLY.

See the important note about SMS Opt In.
smsAttemptList
ListN/A
List of related SmsAttempt objects. See object definition below. For requests sent prior to Nov 2020, this field may be missing/empty. READONLY.

See the important note about SMS Opt In.
locationId
Numeric10
The id for the Location that the Signature is requested for.
statusList
ListN/A
List of signature statuses. See object definition below. READONLY
eventRecipientList
ListN/A
List of EventRecipient objects. See object definition below. These recipients will receive a notification for a final Flow status of COMPLETED, DISPUTED, EXPIRED, FAILED.
qrCode
AlphanumericN/A
Base64 encoded string that can be converted to a QR code image that contains the signatureUrl. READONLY

-QR Code

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/{signatureId}/qrcode
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/{signatureId}/qrcode

GET to retrieve a QR code in PNG format that contains the signatureUrl as an alternative to converting a Signature object’s qrCode base64 string to an image.

-SMS Opt In Waiting

How to know when a FLOW’s SMS is in the queue, waiting for a YES response from the Recipient

When a Flow is requested with a mobileNumber, we will attempt to send the FLOW SMS. However, starting September 27, 2021, before your first SMS is delivered to a recipient, the recipient will be sent an SMS Opt-in Request from PDCflow asking them to confirm that they do want to receive SMS from your company via PDCflow. This is the SMS Opt-in Request that PDCflow will send:

{firstName} {lastName}, {companyName} wants to send you PDCflow smart requests so that you can complete electronic transactions: text YES to receive these requests. Msg&data rates may apply. Reply STOP to opt-out anytime.

The FLOW will still be created and when the recipient responds “YES”, the SMS FLOW Request, which includes the link to the FLOW, will be sent. Now that the recipient has opted in, any future requests to their mobileNumber will be sent. If they ever respond with STOP, they will be unsubscribed from receiving SMS from PDCflow, and new FLOW requests will be rejected before they are created.

To identify if a FLOW is waiting for the SMS recipient to OPT IN, on the initial response and subsequent GETs, you will see there is a mobileNumber, but the smsNotificationIdList will be missing/empty. As soon as the recipient opts in, the waiting flow(s) will now have a Notification ID in the “smsNotificationIdList”.

The FLOW’s SMS is Queued and Waiting For SMS Opt-in if:

Patch Signature

PATCH a PatchSignature object to update an existing Signature for a specific signatureId.


test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/{signatureId}
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/{signatureId}

Response

The updated Signature


PatchSignature

Attribute Description
roundTripNVPS
ListN/A
List of RoundTripNVP objects. These are Name/Value pass-through values.

Any RoundTripNVP with a new rtName will add to the existing list. Any RoundTripNVP with an rtName that matches an existing RoundTripNVP will save the updated rtValue.
Constraint(s): Max of 10 RoundTripNVP objects per request.

SearchParameters

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/search
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/search

POST to retrieve a list of signature transactions.

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures

GET to retrieve a list of signature transactions. URL encode all values for request.

Attribute Description
flowIdList
List - Alphanumeric20
List of Flow IDs.

NOTE: This option will ignore other search options.
startDate
Date25
The starting date for the report range.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
Default: One month prior to today’s date
endDate
Date25
The ending date for the report range.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
firstName
Alpha45
The first name to filter the report results by. Adding a “%” to the end of the name will allow wildcard search.
lastName
Alpha45
The last name to filter the report results by. Adding a “%” to the end of the name will allow wildcard search.
reportType
AlphaN/A
Required
What type of report to retrieve.
Valid value(s):
ALL - Retrieve all signature requests.
SIGNATURE - Retrieve only requests with that include a signature.
ALLDOCUMENTS - Retrieve only requests with attached documents.
SINGLEDOCUMENT - Retrieve only requests with the specified documentId attached.
ACHPAYMENT - Retrieve only requests with an attached ACH payment.
CCPAYMENT - Retrieve only requests with an attached Credit Card payment.
ALLPAYMENT - Retrieve only requests with an attached payment.
documentId
Numeric20
Conditional
The document Id to filter SINGLEDOCUMENT type reports.
usernameList
ListN/A
A list of usernames to filter reports by. Each username is limited to a string with a length of 75 characters.
currentStatusList
ListN/A
A list of statuses to filter the results by.
Valid value(s):
PENDING - The request has been sent.
OPEN - A valid PIN has been entered on the request, but the request has not been completed.
COMPLETED - The request has been successfully completed.
FAILED - The request has failed. This can be due to the document being denied, the request being manually closed, etc. An errorCode and errorMessage will provide the reason for the failure.
EXPIRED - The request has exceeded the timeoutMinutes and cannot be completed.
accountNumberList
ListN/A
A list of account numbers to filter the results by. Each value will be treated as a wildcard search.
locationIdList
ListN/A
A list of location ids to filter the results by. If “0” is contained within the list, the search results will include signatures with no locationId
searchRoundTripNVPList
ListNA
A list of SearchRoundTripNVP objects to filter the results by.
templateNameList
ListN/A
A list of flow template names to filter the results by.
accountDirectiveList
ListN/A
Filters search to contain flows with Payments using any of the specified accountDirectives.
In addition to specific accountDirectives, adding a value of 0 to the list will filter the search to contain flows that don’t have an accountDirective associated with them.
recordStart
Numeric20
The record count to start on.
Default: 0
recordCount
Numeric4
How many records to return.
Default: 2000
Maximum: 5000
retrieveOnlyCompletedRequests
BooleanN/A
Whether to retrieve only signature requests that have been closed. This field has been deprecated in favor of using currentStatusList with a COMPLETED value.
Valid value(s): true, false
Default: false
Constraint(s): Will return a validation error if used in conjunction with currentStatusList that contains any values other than COMPLETED
userId
Alphanumeric75
The user Id to filter reports by. This field has been deprecated in favor of using usernameList

-SignatureList

Attribute Description
signatureList
ListN/A
A list of Signature objects returned from a report request. Result parameters (For a detailed explanation of each response parameter, see Signature):
signatureId
firstName
lastName
emailAddress
mobileNumber
username
companyOverride (if applicable)
– companyName
– emailFromName
– subject
– linkText
payment (if applicable)
– accountNumber
– paymentTransactionId
– paymentType
– totalAmount
document (if applicable)
– documentId
imageUpload (if applicable)
– imageUploadId
standaloneSignatureRequested
completionDate
signatureClosed
errorCode
errorMessage
requestedDate
status
statusDate
expirationDate
locationId
roundTripNVPS

Summary Totals

POST FlowSummarySearchParameters for a FlowSummarySearch object which contains Flow Summary Totals.


Test URL:
https://flowdemo.pdcflow.com/api/v2_0/signatures/summary
Live URL:
https://flow.pdcflow.com/api/v2_0/signatures/summary

Response

FlowSummarySearch object


FlowSummarySearchParameters

Attribute Description
startDate
Date19
Required
The starting date and time for the report range.
Format: URL Encoded ISO-8601 (YYYY-MM-dd HH:mm:ss)
endDate
Date19
The ending date and time for the report range.
Format: URL Encoded ISO-8601 (YYYY-MM-dd HH:mm:ss)
dateSearched
Alpha20
The date which startDate and endDate will apply.
Valid value(s):
  • RECEIVED - Search by signatureReceivedDate
  • CURRENT_STATUS - Search by statusDate
Default: RECEIVED
columnGroupList
List - Alpha
The fields to show and group the Flows by. A field will show in the FlowSummary object.
Valid value(s):
  • day - The flowDate formatted as YYYY-MM-dd.
  • month - The flowDate formatted as YYYY-MM.
  • year - The flowDate formatted as YYYY.
  • pageType
  • username
  • locationId
  • templateName
  • currentStatus
  • transactionOrigin
  • roundTripNVPS.{rtName} - For example roundTripNVPS.employee. The columnGroupList can contain multiple roundTripNVPS.{rtName} fields.
NOTE: The flowDate is the Flow statusDate when dateSearched is CURRENT_STATUS, otherwise it is signatureReceivedDate
usernameList
List - AlphaNumeric75
List of Usernames. Searching for a Username of 0 (zero) will find Flows without a Username.
locationIdList
List - Numeric10
List of Location IDs. Searching for a Location ID of 0 (zero) will find Flows without a Location ID.
templateNameList
List - AlphaNumeric50
List of Template Names. Searching for a Template Name of 0 (zero) will find Flows without a Template Name.
transactionOriginList
List - Alphanumeric3
List of Transaction Origins. This will typically be EXT.
NOTE: There are other possible values. Please contact our Customer Success team to learn more.
pageTypeList
List - Alpha
List of Page Types.
Valid value(s):
  • PG_DOC - Document Page
  • PG_FIL - File Uploads Page
  • PG_IMG - Image Upload Page
  • PG_PAY - Payment Page
  • PG_PMT - Payment Portal Page
  • PG_RBD - Request Billing Data Page
  • PG_SCH - Schedule Authorization Page
  • PG_SCP - Schedule Payment Page
  • PG_SIG - Signature Page
Default: All PageTypes
currentStatusList
List - Alpha
A list of Flow Statues.
Valid value(s):
  • PENDING - The request has been sent.
  • OPEN - A valid PIN has been entered on the request, but the request has not been completed.
  • COMPLETED - The request has been successfully completed.
  • EXPIRED - The request has exceeded the timeoutMinutes and cannot be completed.
  • FAILED - The request has failed. This can be due to a page being denied, the request being manually closed, etc.
Default: All FlowStatuses
searchRoundTripNVPList
List
List of SearchRoundTripNVP objects.


FlowSummarySearch

Attribute Description
totalFlowCount
Numeric
Readonly
Total Count for all Flows matching the FlowSummarySearchParameters

Shown if columnGroupList does not contain pageType.
totalPageCount
Numeric
Readonly
Total Count for all Flow Pages matching the FlowSummarySearchParameters

Only shown if columnGroupList contains pageType.
flowSummaryListSize
Numeric
Readonly
Size of the flowSummaryList
flowSummaryList
List - Object
Readonly
List of FlowSummary group objects with fields shown based on the provided columnGroupList


FlowSummary

Attribute Description
flowCount
Numeric
Readonly
Total Count for Flows in the group
day
Alphanumeric
Readonly
The flowDate formatted as YYYY-MM-dd for Flows in the group. The flowDate is the Flow statusDate when dateSearched is CURRENT_STATUS, otherwise it is signatureReceivedDate

Only shown if columnGroupList contains day.
month
Alphanumeric
Readonly
The flowDate formatted as YYYY-MM for Flows in the group. The flowDate is the Flow statusDate when dateSearched is CURRENT_STATUS, otherwise it is signatureReceivedDate

Only shown if columnGroupList contains month.
year
Alphanumeric
Readonly
The flowDate formatted as YYYY for Flows in the group. The flowDate is the Flow statusDate when dateSearched is CURRENT_STATUS, otherwise it is signatureReceivedDate

Only shown if columnGroupList contains year.
pageType
Alphanumeric
Readonly
The pageType for Flows in the group.
Valid value(s):
  • PG_DOC - Document Page
  • PG_FIL - File Uploads Page
  • PG_IMG - Image Upload Page
  • PG_PAY - Payment Page
  • PG_PMT - Payment Portal Page
  • PG_RBD - Request Billing Data Page
  • PG_SCH - Schedule Authorization Page
  • PG_SCP - Schedule Payment Page
  • PG_SIG - Signature Page
Only shown if columnGroupList contains pageType.
username
Alphanumeric
Readonly
The username for Flows in the group.

Only shown if columnGroupList contains username.
locationId
Numeric
Readonly
The locationId for Flows in the group.

Only shown if columnGroupList contains locationId.
templateName
Alphanumeric
Readonly
The templateName for Flows in the group.

Only shown if columnGroupList contains templateName.
currentStatus
Alphanumeric
Readonly
The status for Flows in the group.
Valid value(s):
  • PENDING - The request has been sent.
  • OPEN - A valid PIN has been entered on the request, but the request has not been completed.
  • COMPLETED - The request has been successfully completed.
  • EXPIRED - The request has exceeded the timeoutMinutes and cannot be completed.
  • FAILED - The request has failed. This can be due to a page being denied, the request being manually closed, etc.
Only shown if columnGroupList contains currentStatus.
transactionOrigin
Alphanumeric
Readonly
The transactionOrigin for Flows in the group.

Only shown if columnGroupList contains transactionOrigin.
roundTripNVPS.{rtName}
Alphanumeric
Readonly
The roundTripNVPS.{rtName} for Flows in the group.

Only shown if columnGroupList contains roundTripNVPS.{rtName}.

-Payment

Attribute Description
paymentTransactionId
Numeric20
The confirmation id of the payment.
accountNumber
Alphanumeric45
Account number associated with payment in this transaction.
dateCreated
Date25
The date and time the payment was entered for processing.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
dateProcessed
Date25
The date and time the payment was processed.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
paymentAmount
NumericString11
The payment amount for this transaction. This attribute also serves as the maximum payment amount. The payer will not be allowed to pay more than the submitted amount, even if editablePaymentAmount is set to true.
Format: XXXXXXXX.XX
editablePaymentAmount
Boolean5
Whether or not the paymentAmount is editable by the payer.
Valid value(s): true, false
Default: false
minimumAmount
NumericString11
If the payer is able to edit the paymentAmount, this is the minimum they can pay.
Format: XXXXXXXX.XX
feeAmount
NumericString11
The fee amount for this transaction.
Format: XXXXXXXX.XX
Constraint(s): Cannot be present if feePercentage is present
feePercentage
Numeric9
The percentage of the payment amount that will be charged as a fee. Presented as a percentage, not a decimal
Format: XXX.XXXXXX
Constraint(s):
-Cannot be present if feeAmount is present
-Cannot be greater than 4
totalAmount
NumericString11
The total amount for this transaction.
Format: XXXXXXXX.XX
address
Alphanumeric80
The address associated with the payment.
city
Alphanumeric45
The city associated with the payment.
state
Alphanumeric2
The state abbreviation associated with the payment.
zip
NumericString9
The zip code associated with the payment.
paymentType
Alpha3
Type of payment to include in the request.
Constraint(s): If present, the payment object will be used to make a payment. Also if present, a PAYMENT_PORTAL component cannot be used. If not present, the payment details will only be used on the standalone signature image.
Valid value(s): ACH, CC, ALL
achTransaction
ObjectN/A
Data to preload for ACH payment request.
Constraint(s): See object definition below.
ccTransaction
ObjectN/A
Data to preload for credit card payment request.
Constraint(s): See object definition below.
accountDirective
Deprecated
This element is deprecated. Use the accountDirective within AchTransaction and CreditCardTransaction.

-AchTransaction

Attribute Description
achStatusData
ListN/A
List of achStatusData objects for this ach transaction.
Constraint(s): See object definition below.
accountDirective
Alphanumeric10
The account directive if an ach payment is processed.
Format: XXX-X
bankAccountNumber
Alphanumeric20
The payer’s bank Token or a raw bank account number for ACH transaction.
To create a token, see Secure Overlay API and/or TokenizationService.
NOTE: Providing a raw bank account number is deprecated
Constraint(s): Will be preloaded on form for client, though they will be able to edit it.
bankRoutingNumber
NumericString9
The payer’s bank routing number for ACH transaction.
This value is retrieved from a token bankAccountNumber if not provided.
Constraint(s): Will be preloaded on form for client, though they will be able to edit it.
bankAccountNumberLastFour
NumericString20
The last four numbers of the payer’s bank account number.
checkNumber
NumericString9
The payer’s check number for transaction.
Constraint(s): Will be preloaded on form for client, though they will be able to edit it.
bankAccountType
Alpha8
The type of bank account.
This value is retrieved from a token bankAccountNumber if not provided.
Constraint(s): Will be preloaded on form for client, though they will be able to edit it.
Valid value(s): CHECKING, SAVINGS

-AchStatusData

Attribute Description
status
Alpha12
The status of the ACH transaction
Valid value(s):
WAITING - transaction will be included in next batch
SUBMITTED - transaction has been submitted for processing
ACKNOWLEDGED - transaction has been accepted for processing
FUNDED - money has been deposited into your account
DEDUCTION - money has been taken from your account
VOID - transaction was cancelled prior to submission for processing
RETURNED - an exception occurred while processing transaction
CORRECTION - transaction was automatically corrected during processing
ERROR - an unknown error occurred while processing transaction
returnCode
Alpha8
The return code for the ACH transaction, if applicable.
returnMessage
AlphanumericN/A
Explanation of the returnCode.
statusChangeDate
Date25
Date and time this ACH status was recorded.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)

-CreditCardTransaction

Attribute Description
accountDirective
Alphanumeric10
The account directive if a card payment is processed.
Format: XXX-X
creditCardExpirationMonth
Numeric2
Expiration month of the payer’s credit card.
This value will be retrieved from the creditCardToken if not provided.
Constraint(s): Will be preloaded on form for client, though they will be able to edit it.
creditCardExpirationYear
Numeric4
Expiration year of the payer’s credit card.
This value will be retrieved from the creditCardToken if not provided.
Constraint(s): Will be preloaded on form for client, though they will be able to edit it.
creditCardToken
Alphanumeric16
Credit card token as generated by PDC4U. An actual credit card number will fail validation.
Constraint(s): Will be preloaded on form for client, though they will be able to edit it or enter a different card number.

See the Store a credit card in the vault example in the Credit Card API for help generating the token.
creditCardType
Alpha50
The type of the payer’s credit card.
authorizationCode
Alphanumeric75
The authorization code for the processed transaction

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/{signatureId}/resend
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/{signatureId}/resend

PUT to resend the Signature link to the emailAddress and/or mobileNumber stored with the Signature.

-Document

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/documents

POST to document endpoint to upload a document.
GET to retrieve a previously uploaded document.

Attribute Description
documentName
Alphanumeric36
The name given for the document.
documentBase64String
Base64N/A
The document as a Base64 encoded string.
documentId
Numeric20
Id for document that was uploaded. Can be sent in future requests to reuse document without uploading it again.
documentUrl
Alphanumeric160
The URL to retrieve the information, through a GET request, for this document.
originalUploadDate
Date25
The date and time the document was originally uploaded.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
overlayId
Numeric20
The id of an uploaded overlay to apply to this document in the request

-Overlay

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays
live endpoint: [https://flow.pdcflow.com/FlowService/api/v2_0/overlays/[overlayId](https://flow.pdcflow.com/FlowService/api/v2_0/overlays/[overlayId])

Send a POST request with the following parameters to the overlays endpoint to create a new Overlay
Send a GET request with an overlayId to the overlays endpoint to retrieve a Overlay
Send a GET request without an overlayId to the overlays endpoint to retrieve a list of Overlay objects
Send a PUT request with an overlayId to the overlays endpoint with a command parameter to modify or delete an existing Overlay. Valid command values are EDIT and DELETE

Attribute Description
originalDocumentId
NumericN/A
The id of the reference document
overlayName
Alphanumeric36
A user defined name to assign to the Overlay
overlayBoxDefinitionList
ListN/A
A list of overlayBox objects.
Constraint(s): see object definition below
overlayId
NumericN/A
Readonly
The id of the Overlay
createdDate
Date25
Readonly
The date the overlay was originally created. Returned on Overlay creation and retrieval
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
lastModifiedDate
Date25
Readonly
The date the overlay was last updated. Returned on Overlay retrieval
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)

-OverlayBox

Attribute Description
boxTypeId
NumericN/A
The id indicating the box type. Valid values:
- 1: Signifies a smaller signature box*
- 2: Signifies an uneditable date box that contains the current date
- 3: Signifies a check box
- 4: Signifies a larger signature box*
- 5: Signifies a text box*
*If present, an end user must populate these boxes to complete the signature successfully
startXPercent
NumericN/A
Starting draw position as a percentage from the left side of the document
startYPercent
NumericN/A
Starting draw position as a percentage from the top of the document
documentPage
NumericN/A
The page on the uploaded document to which to assign the OverlayBox
boxProperties
ObjectN/A
Properties for the OverlayBox. Only applicable to text boxes. All other box types have fixed properties.
Constraint(s): see object definition below
boxTypeLabel
AlphanumericN/A
Readonly
Text label for an OverlayBox. Returned on Overlay retrieval. Possible values:
- Signature
- Date
- Checkbox
- Big Signature
- UserText
boxType
AlphanumericN/A
Readonly
Predefined name for box type. Returned on Overlay retrieval. Possible values:
- SIGNATURE
- DATE
- CHECK
- TEXT

-BoxProperties

Attribute Description
boxHeight
NumericN/A
Height of the text box in pixels.
Default: 50
boxWidth
NumericN/A
Width of the text box in pixels.
Default: 200
fontSize
NumericN/A
Font size of the text box
characterLimit
NumericN/A
Character limit for the text box. If left blank, this value will be calculated using boxHeight, boxWidth, and fontSize

-ImageUploadList

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/imageUploads/allUploads/[signatureId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/imageUploads/allUploads/[signatureId]

GET to retrieve a list of images from a previous signature request.

Attribute Description
imageUploadList
ListN/A
A list of ImageUpload objects uploaded by your client. Constraint(s): see object definition below.

-ImageUpload

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/imageUploads
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/imageUploads

GET to retrieve an image from a previous signature request.

Attribute Description
imageUploadRequested
Boolean5
Whether to request an image upload from the client.
Valid value(s): true, false
Default: false
imageUploadId
Numeric20
Id for the image that was uploaded by the client.
signatureId
Numeric20
The id of the transaction request this image is tied to.
imageUploadSuccessful
Boolean5
Whether the upload was successful or not.
Valid value(s): true, false
imageUploadDescription
Alphanumeric160
A description of the image for the client to upload.
Default: Upload Image
ImageUploadBase64
Base64N/A
Base64 encoded value of the .png format uploaded image.
signatureUrl
Alphanumeric160
The URL to retrieve the information, through a GET request, for this transaction.
imageUploadUrl
Alphanumeric160
The URL to retrieve the information, through a GET request, for this image upload.

-CompanyOverride

Attribute Description
companyName
Alphanumeric45
The company name to display on the signature, if different than the company sending the request. If this value is included in the request, the configured company logo will not show for this request.
emailFromName
Alphanumeric50
The name to display on from field of the signature email request.
Default: The sending Company’s Name (or provided overrideCompanyName) will be used
subject
Alphanumeric50
The subject to display on the signature email request.
Default: The sending Company’s Name (or provided overrideCompanyName) will be used
linkText
Alphanumeric25
The text to display on the clickable URL in the signature email request.
Default: Complete Transaction

-Component

Attribute Description
componentType
AlphaN/A
The type of this component.
Valid values:
  • PAYMENT_PORTAL
  • BILLING_DATA
  • SCHEDULE
  • FILE_UPLOAD
Constraint(s): If a payment object with a paymentType is sent with the signature, a PAYMENT_PORTAL componentType cannot be used.
relatedId
Alphanumeric24
Conditional
The id of the object represented by this component.
Conditional notes:
  • Required if componentType is SCHEDULE
  • For PAYMENT_PORTAL this is a READONLY value that will be set to the paymentTransactionId of a successful payment.
  • Not used for BILLING_DATA or FILE_UPLOAD
data
ObjectN/A
Conditional
Object for a given componentType
Object definition links:

–PAYMENT_PORTAL Component Data

Attribute Description
portalUrl
AlphaNumeric200
Required
The full URL of the portal.
requestSignature
Boolean
Option to specify if the Portal Payment page should request a signature.
signatureDescription
Alphanumeric160
Custom text to display with the signature. Only used if requestSignature is true.
customReceiptText
Alphanumeric5000
Custom text to show on the Receipt. If not provided, the service will use the company default.
customReceiptLabels
ObjectN/A
A Name/Value list of CustomReceiptLabels to show on the Receipt. If a label is sent, it must be accompanied by a value.
portalPrePopulateVariables
ObjectN/A
See object definition
portalResponse
ObjectN/A
READONLY
The response from the payment portal.
See object definition below.

Example Code

portalResponse

Attribute Description
transactionStatus
AlphaN/A
The result of the portal payment.
Valid values: APPROVED, FAILED, DENIED
arrivalId
Numeric10
The arrivalId of the payment.
transactionId
Numeric10
The transactionId of the payment.
paymentMethod
AlphaN/A
The payment method entered in the portal.
Valid values: CARD, CHECK
uuid
AlphaNumeric36
A unique id used internally by the service.

–BILLING_DATA Component Data

Attribute Description
paymentTypeRequest
ListN/A
Required
List of payment types to select from.
Valid value(s): CARD, CHECK
authorizationTextOverride
Alphanumeric500
Conditional
Text to display at the bottom of the input form for the authorization check box.
paymentType
Alpha5
READONLY
The payment type selected by the end user.
Valid value(s): CARD, CHECK
ccDetails
Object
conditional
READONLY
Only returned if paymentType is CARD
See object definition below.
achDetails
Object
conditional
READONLY
Only returned if paymentType is CHECK
See object definition below.

ccDetails

Attribute Description
token
AlphaNumeric16
The Tokenized credit card number.
cardExpirationMonth
Numeric2
The card expiration month.
cardExpirationYear
Numeric2
The card expiration year.

achDetails

Attribute Description
bankRoutingNumber
Numeric9
The bank routing number.
bankAccountNumber
Numeric20
The bank account token.
bankAccountType
Alpha8
The bank account type.
Valid value(s): CHECKING, SAVINGS

–SCHEDULE Component Data

Attribute Description
requestPaymentData
Boolean
READONLY
Boolean stating if the Schedule is requesting Payment Data
requestAuthorization
Boolean
READONLY
Boolean stating if the Schedule is requesting Authorization
paymentTypes
ListN/A
READONLY
Allowed Payment Types for this Schedule
Valid value(s): CARD, CHECK

–FILE_UPLOAD Component Data

Attribute Description
fileUploadList
List5
Required
List of FileUpload objects.

Example Code

FileUpload

Attribute Description
fileId
AlphaNumeric
Readonly
An auto generated ID for the file.
description
AlphaNumeric75
Required
A description of the file being requested for the client to upload.
fileType
AlphaN/A
The type of file being requested. This will limit the type of files a client can upload.
Valid values:
  • IMAGE: An Image such as jpg, png, etc
  • PDF: A PDF document
  • FILE: Can be either an Image or PDF
Default: FILE
isRequired
Boolean5
Whether the file is required by the client or not.
Default: true
fileName
AlphaNumeric
Readonly
The name of the file uploaded by the client.
fileBase64
AlphaNumeric
Readonly
The file uploaded by the client as a Base64 encoded value.

statusList

Attribute Description
status
Alpha9
The status of the request.
Valid value(s):
PENDING - The request has been sent.
OPEN - A valid PIN has been entered on the request, but the request has not been completed.
COMPLETED - The request has been successfully completed.
FAILED - The request has failed. This can be due to the document being denied, the request being manually closed, etc. An errorCode and errorMessage will provide the reason for the failure.
EXPIRED - The request has exceeded the timeoutMinutes and cannot be completed.
statusDate
Date25
The date that this status happened. For an EXPIRED status, this will be the date the request expired. For requests sent prior to June 2019, this field may be empty.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)

-EmailAttempt

Attribute Description
attemptDate
Date25
Readonly
The date and time the Email was attempted to send.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
attemptResult
Alphanumeric10
Readonly
The result status of the sending Attempt.
Valid value(s):
SENT = email was successfully sent to the email provider
FAILED = email was sent to the email provider, but rejected and will not be retried
RETRY = email was not able to send to the email provider, but will be retried
emailDeliveryResultList
ListN/A
Readonly
List of related EmailDeliveryResult objects. See object definition below

-EmailDeliveryResult

Attribute Description
result
Alphanumeric30
Readonly
Delivery Result for a SENT Email attempt
Valid value(s):
SEND = email provider acknowledged they received the email
DELIVERY = email provider successfully delivered the email
BOUNCED = email provider was not able to deliver the email
OPEN = email was opened by recipient
CLICK = an email link was clicked by recipient
COMPLAINT = email was reported as spam/abuse by recipient
resultDate
Date25
Readonly
The date and time of the Email delivery result
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)

-SmsAttempt

Attribute Description
attemptDate
Date25
Readonly
The date and time the SMS was attempted to send
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
status
AlphaN/A
Readonly
The result status of the sending attempt
Valid value(s):
ACCEPTED = the SMS has been accepted by the processing vendor
SENT = the phone carrier has accepted the SMS
DELIVERED = the SMS was successfully delivered
UNDELIVERED = the SMS was not delivered
FAILED = the SMS could not be sent
statusDate
Date25
Readonly
The date and time the status was updated
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)

-RoundTripNVP

Attribute Description
rtName
Alphanumeric75
Required
The name of a round trip name value pair.
rtValue
Alphanumeric75
Required
The value of a round trip name value pair.

-EventRecipient

Attribute Description
emailAddress
Alphanumeric75
Required
An Email address to receive an event notification.

-SearchRoundTripNVP

Attribute Description
rtName
Alphanumeric75
Required
The name of a round trip name value pair to filter a search by.
Constraint(s): Each name must be unique
rtValueList
ListN/A
Required
A list of values of a round trip name value pair to filter a search by
If the list contains a value of -1, the results will also be filtered to include signatures that do not contain a RoundTripNVP with the specified name
If the list contains a value of 0, the results will also be filtered to include signatures that contain a RoundTripNVP whose value is null for the specified name. This functionality is designed for legacy signatures as PDCflow now requires all RoundTripNVP objects to contain both a name and value.
Constraint(s): Each value must not exceed 75 characters

TransactionReport

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/transactionReports
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/transactionReports

GET to retrieve a transaction report for a signature transaction. If this flow is an authorization request for a schedule, the schedule will be included in this report, along with the signature if the authorization request was completed.

Attribute Description
signatureId
Numeric20
Required
The id of the transaction request to retrieve a report for.
reportType
Alpha7
The desired type of the transaction report. FULL will return the full transaction report. RECEIPT will return a report with the signature image, any related payment information and any attached document.
Valid value(s): FULL, RECEIPT
Default: FULL
emailAddress
Alphanumeric65
An email address to send the transaction report to.
reportData
Base64N/A
The full transaction report pdf as a Base64 encoded value.
closedOrExpired
Boolean5
Whether the request has been closed or expired or not.
Valid value(s): true, false

Account Directive Migration

test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/migrations/accountdirectives
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/migrations/accountdirectives

PATCH to the endpoint with an AccountDirectiveMigration body to migrate all PENDING and OPEN signatures from one accountDirective to another. Only signatures with a Payment and/or SCHEDULE component will be affected. Returns a MigrationResponse. This is an asynchronous process and realtime processing results will not be returned.

Attribute Description
oldAccountDirective
Alphanumeric String 10
Required
The accountDirective currently assigned to the targeted signatures.
newAccountDirective
Alphanumeric String 10
Required
The desired accountDirective to assign to the targeted signatures.
Constraint(s): Must be valid for the same payment method as the oldAccountDirective.
If the payment method is CARD, this field must allow at least the same card types as the oldAccountDirective.
If the payment method is CHECK, this field must be valid for the same SEC code as the oldAccountDirective

MigrationResponse

Attribute Description
response
String
A description of the processing status.
requestErrorList
List
A list of RequestError objects. Only returned on unsuccessful migrations.

PostBack Flow Events

Basic information about a Flow can be sent back to your system for some Flow events. The information returned can be used to securely GET further details from Flow Service. The PostBackBody will always come as JSON using an HTTPs POST.

If something goes wrong attempting to postback to your system, we will automatically retry on this schedule:

To be considered successful, we expect your server to return HTTP STATUS 200. Once that is received or after Attempt #5 we will no longer try to post the data.

To enable sending, please log into your app.pdcflow.com account and navigate to CONFIGURE > NOTIFICATIONS. This is where you can configure PostBacks for each Flow event:

Event Description
FLOW_COMPLETED A Flow has been completed.
FLOW_DISPUTED A Flow has been disputed.
FLOW_EXPIRED A Flow has expired.
FLOW_FAILED A Flow has failed.

-PostBackBody

Attribute Description
signatureId
Numeric20
The PDC Signature/Flow ID, always present. Use this to pull further details on a payment from Flow Service.
companyId
Numeric8
The PDC Company ID for the Flow.
completionDate
Date25
The date and time the request was completed.
Format: ISO-8601 (YYYY-MM-DD HH:mm:ss)
errorCode
Alpha3
Code if an error occurred with the signature. See errorMessage for possible values.
errorMessage
Alphanumeric160
An explanation message for the error that occurred.
Constraint(s): Will only show if an errorCode is present.
Valid values for an errorCode:
  • DEV - Device not compatible
  • DSP - Attached document was disputed
  • EMP - Signature image is empty
  • ERR - Error processing request
  • FIC - File upload cancelled
  • FIL - Failed to save signature
  • IMC - Image upload request denied
  • INV - Invalid request
  • LCK - Transaction already closed
  • MAN - Transaction has been closed
  • NFN - Signature not found
  • PIN - Pin verification failed
  • PMD - Permission denied
  • PPC - Payment portal canceled
  • SDS - Attached schedule was disputed
  • SAF - Schedule activation failed
  • SES - Session invalid. Log in and try again
  • TMO - Transaction request expired
  • USB - Unsupported browser. Please upgrade to a newer browser

RequestErrorList

Attribute Description
requestErrorList
ListN/A
A list of RequestError objects containing validation errors.
Constraint(s): Only returned when validation errors occur. See object definition below.

RequestError

Attribute Description
code
Alpha3
The code for the validation error.
description
AlphanumericN/A
The description of the validation error.

Sample Use Case

While the signature service offers many different types of functionality, knowing how to tie them all together can be a bit tricky. Below are some potential work-flows that you may encounter, and the API components that should be used. The components can be used separately, or as a group.

-Get signatures on a mortgage document and image of some form of identification

<?php
$data = [
  'document' => [
    'documentId' => 'ID_FROM_STEP_1',
    'overlayId' => ''
  ],
  'imageUpload' => [
    'imageUploadDescription' => 'Take a picture of some form of identification',
    'imageUploadRequested' => 'true'
  ],
  'standaloneSignatureRequested' => 'true'
];
my $data = {
  'document' => {
    'documentId' => 'ID_FROM_STEP_1',
    'overlayId' => ''
  },
  'imageUpload' => {
    'imageUploadDescription' => 'Take a picture of some form of identification',
    'imageUploadRequested' => 'true'
  },
  'standaloneSignatureRequested' => 'true'
};
data = {
  'document' => {
    'documentId' => 'ID_FROM_STEP_1',
    'overlayId' => ''
  },
  'imageUpload' => {
    'imageUploadDescription' => 'Take a picture of some form of identification',
    'imageUploadRequested' => 'true'
  },
  'standaloneSignatureRequested' => 'true'
};

Components required: Signature, Document, ImageUpload

-Get a signature on a recurring payment schedule

<?php
$data = [
  'document' => [
    'documentId' => 'ID_FROM_STEP_1',
    'overlayId' => ''
  ],
  'standaloneSignatureRequested' => 'true'
];
my $data = {
  'document' => {
    'documentId' => 'ID_FROM_STEP_1',
    'overlayId' => ''
  },
  'standaloneSignatureRequested' => 'true'
};
data = {
  'document' => {
    'documentId' => 'ID_FROM_STEP_1',
    'overlayId' => ''
  },
  'standaloneSignatureRequested' => 'true'
};

Components required: Signature, Document

Sample Code

This section offers some client implementation examples in different languages. Keep in mind, these are only minimalistic examples used to demonstrate the Signature Service REST API and are not meant for production use.

-Result Status Codes

Expected HTTP Status codes

Status '200':
Description = 'Success.'

Status: '400':
Description = 'Malformed request. The request is either incorrectly formatted, or there are validation errors.'

Status '401':
Description = 'Invalid credentials.'

Status '403':
Description = 'Service not activated.'

Status '404':
Description = 'The requested signature/document/image was not found.'

Status '405':
Description = 'POST, GET, PUT request not supported for resource.'

Status '500':
Description = 'An internal error has occurred.'

All requests will return a status code. For example, in the case of status code 400, check for a requestErrorList in the response, containing information on validation failure.

General signature requests will use this method. It will send a text or email or both to the specified emailAddress, mobileNumber.

Send a HTTP POST request, with the required data, to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures

-Send Signature Request

<?php
$paymentType = 'CARD';
$payment = [
  'accountNumber' => 'YourAccountNumber',
  'paymentAmount' => '$125.00',
  'feeAmount' => '$5.00',
  'feePercentage' => 0,
  'accountDirective' => '0000',
  'editablePaymentAmount' => 'true',
  'minimumAmount' => '100.00'
];
if($paymentType == 'CARD') {
  $payment['paymentType'] = 'CC';
  $payment['ccTransaction'] = [
    'creditCardExpirationMonth' => '09',
    'creditCardExpirationYear' => '2022',
    'creditCardToken' => 'CardTokenFromPDC'
  ];
}
else if($paymentType == 'CHECK') {
  $payment['paymentType'] = 'ACH';
  $payment['achTransaction'] = [
    'bankAccountNumber' => 'aBankToken123456',
    'bankAccountNumberLastFour' => '3456',
    'bankAccountType' => 'CHECKING',
    'bankRoutingNumber' => '124001545',
    'checkNumber' => '1'
  ];
}

$roundTripList = [];
$roundTripList[] = [
  'rtName' => 'personalIdNumber',
  'rtValue' => '1234Number'
];

$data = [
  'customMessage' => 'Thank you for buying!',
  'description' => 'Agreement for mortgage.',
  'emailAddress' => 'frontenduser@pdc4u.com',
  'firstName' => 'Adam',
  'lastName' => 'Test',
  'maxPinAttempts' => '2',
  'mobileNumber' => '7777777777',
  'pinDescription' => 'Last four of your social security number',
  'verificationPageHeader' => 'Text that will be displayed at the top of the verification page',
  'redirectLink' => 'https://www.pdcflow.com',
  'requestGeolocation' => 'true',
  'roundTripNVPS' => $roundTripList,
  'payment' => $payment,
  'companyOverride' => [
    'companyName' => 'Our Child Company'
  ],
  'document' => [
    'documentId' => '1',
    'overlayId' => ''
    //Specify to include an overlay                         
  ],
  'imageUpload' => [
    'imageUploadDescription' => 'Upload photo id',
    'imageUploadRequested' => 'true',
  ],
  'standaloneSignatureRequested' => 'true',
  'templateName' => 'SignatureOnly',
  'timeoutMinutes' => '4.5',
  'transactionOrigin' => 'EXT',
  'username' => 'someuser@pdc4u.com',
  'verificationPin' => '1235',
  'postbackUrl' => 'https://www.testpostbackaddress.com'
];

$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures';

$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data)
  ]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $paymentType = 'CARD';
   my %payment = (
      'accountNumber' => 'YourAccountNumber',
      'paymentAmount' => '$125.00',
      'feeAmount' => '$5.00',
      'feePercentage' => '0',
      'accountDirective' => '0000',
      'editablePaymentAmount' => 'true',
      'minimumAmount' => '100.00'
   );
   if($paymentType eq 'CARD') {
      $payment{'paymentType'} = 'CC';
      $payment{'ccTransaction'} = {
         'creditCardExpirationMonth' => '09',
         'creditCardExpirationYear' => '2022',
         'creditCardToken' => 'CardTokenFromPDC'
      };
   }
   elsif ($paymentType == 'CHECK'){
      $payment{'paymentType'} = 'ACH';
      $payment{'achTransaction'} = {
         'bankAccountNumber' => 'aBankToken123456',
         'bankAccountNumberLastFour' => '3456',
         'bankAccountType' => 'CHECKING',
         'bankRoutingNumber' => '124001545',
         'checkNumber' => '1'
      };
   }
   my $roundTripList = [ {'rtName'=>'personalIdNumber'}, {'rtValue'=>'1234abcd'} ];

   my $data = {
      'customMessage' => 'Thank you for buying!',
      'description' => 'Agreement for mortgage.',
      'emailAddress' => 'frontenduser@pdc4u.com',
      'firstName' => 'Adam',
      'lastName' => 'Test',
      'maxPinAttempts' => '2',
      'mobileNumber' => '7777777777',
      'pinDescription' => 'Last four of your social security number',
      'verificationPageHeader' => 'Text that will be displayed at the top of the verification page',
      'redirectLink' => 'https://www.pdcflow.com',
      'requestGeolocation' => 'true',
      'roundTripNVPS' => $roundTripList,
      'payment' => \%payment,
      'companyOverride' => {
        'companyName' => 'Our Child Company'
      },
      'document' => {
         'documentId' => '1',
         'overlayId' => '' #Specify to include an overlay
      },
      'imageUpload' => {
         'imageUploadDescription' => 'Upload photo id',
         'imageUploadRequested' => 'true',
      },
      'standaloneSignatureRequested' => 'true',
      'templateName' => 'SignatureOnly',
      'timeoutMinutes' => '4.5',
      'transactionOrigin' => 'EXT',
      'username' => 'someuser@pdc4u.com',
      'verificationPin' => '1235',
      'customEmailBody' => 'We would like to capture authorization that you approve this message. Please click the following link to authorize our transaction.',
      'postbackUrl' => 'https://www.testpostbackaddress.com'
   };

   $data = JSON::XS->new->utf8->encode ($data);

   my $url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures';

   my $req = HTTP::Request->new( 'POST', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin
   paymentType = 'CARD'
   #paymentType = 'CHECK'

   payment = {
      'accountNumber' => 'YourAccountNumber',
      'paymentAmount' => '$125.00',
      'feeAmount' => '$5.00',
      'feePercentage' => '0',
      'accountDirective' => '0000',
      'editablePaymentAmount' => 'true',
      'minimumAmount' => '100.00'
   }

   if paymentType == 'CARD' then
      payment['paymentType'] = 'CC'
      payment['ccTransaction'] = {
         'creditCardExpirationMonth' => '09',
         'creditCardExpirationYear' => '2022',
         'creditCardToken' => 'CardTokenFromPDC'
      }
   elsif paymentType == 'CHECK' then
      payment['paymentType'] = 'ACH'
      payment['achTransaction'] = {
         'bankAccountNumber' => 'aBankToken123456',
         'bankAccountNumberLastFour' => '3456',
         'bankAccountType' => 'CHECKING',
         'bankRoutingNumber' => '124001545',
         'checkNumber' => '1'
      }
   end

   roundTripList = [
      'rtName'=>'personalIdNumber',
      'rtValue'=>'1234abcd'
   ]

   data = {
      'customMessage' => 'Thank you for buying!',
      'description' => 'Agreement for mortgage.',
      'emailAddress' => 'frontenduser@pdc4u.com',
      'firstName' => 'Adam',
      'lastName' => 'Test',
      'maxPinAttempts' => '2',
      'mobileNumber' => '7777777777',
      'pinDescription' => 'Last four of your social security number',
      'verificationPageHeader' => 'Text that will be displayed at the top of the verification page',
      'redirectLink' => 'https://www.pdcflow.com',
      'requestGeolocation' => 'true',
      'roundTripNVPS' => roundTripList,
      'payment' => payment,
      'companyOverride' => {
        'companyName' => 'Our Child Company'
      },
      'document' => {
         'documentId' => '1',
         'overlayId' => '' # Specify to include an overlay
      },
      'imageUpload' => {
         'imageUploadDescription' => 'Upload photo id',
         'imageUploadRequested' => 'true',
      },
      'standaloneSignatureRequested' => 'true',
      'templateName' => 'SignatureOnly',
      'timeoutMinutes' => '4.5',
      'transactionOrigin' => 'EXT',
      'username' => 'someuser@pdc4u.com',
      'verificationPin' => '1235',
      'customEmailBody' => 'We would like to capture authorization that you approve this message. Please click the following link to authorize our transaction.',
      'customEmailFooter' => 'This email has been brought to you by our Corporation.',
      'postbackUrl' => 'https://www.testpostbackaddress.com'
   }

   c = Curl::Easy.new
   c.url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures'
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_post(payload)

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

-Overlay Creation


<?php

$data = [
    'overlayName' => MyOverlayName',
    'overlayBoxDefinitionList' => [
        [
            'boxTypeId' => 5,
            'startXPercent' => 5.798,
            'startYPercent' => 25.755,
            'documentPage' => 1,
            'boxProperties' => [
                'fontSize' => 24,
                'boxWidth' => 520.55,
                'boxHeight' => 120.44,
                'characterLimit' => 40
            ]
        ],
        [
            'boxTypeId' => 2,
            'startXPercent' => 71.336,
            'startYPercent' => 10.151,
            'documentPage' => 1
        ]
    ]
];

$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays';

$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data)
]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, 'someSecretUsername:someSecretPassword');
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {    

   my $data = {
       'overlayName' => MyOverlayName',
       'overlayBoxDefinitionList' => [
           {
               'boxTypeId' => 5,
               'startXPercent' => 5.798,
               'startYPercent' => 25.755,
               'documentPage' => 1,
               'boxProperties' => {
                   'fontSize' => 24,
                   'boxWidth' => 520.55,
                   'boxHeight' => 120.44,
                   'characterLimit' => 40
               }
           },
           {
               'boxTypeId' => 2,
               'startXPercent' => 71.336,
               'startYPercent' => 10.151,
               'documentPage' => 1
           }
       ]
   };

   $data = JSON::XS->new->utf8->encode ($data);

   my $url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays';

   my $req = HTTP::Request->new( 'POST', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin

   data = {
       'overlayName' => MyOverlayName',
       'overlayBoxDefinitionList' => [
           {
               'boxTypeId' => 5,
               'startXPercent' => 5.798,
               'startYPercent' => 25.755,
               'documentPage' => 1,
               'boxProperties' => {
                   'fontSize' => 24,
                   'boxWidth' => 520.55,
                   'boxHeight' => 120.44,
                   'characterLimit' => 40
               }
           },
           {
               'boxTypeId' => 2,
               'startXPercent' => 71.336,
               'startYPercent' => 10.151,
               'documentPage' => 1
           }
       ]
   }

   c = Curl::Easy.new
   c.url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays'
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_post(payload)

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

-Overlay Modification

<?php

$data = [
    'overlayName' => MyOverlayName',
    'overlayBoxDefinitionList' => [
        [
            'boxTypeId' => 5,
            'startXPercent' => 5.798,
            'startYPercent' => 25.755,
            'documentPage' => 1,
            'boxProperties' => [
                'fontSize' => 24,
                'boxWidth' => 520.55,
                'boxHeight' => 120.44,
                'characterLimit' => 40
            ]
        ],
        [
            'boxTypeId' => 2,
            'startXPercent' => 71.336,
            'startYPercent' => 10.151,
            'documentPage' => 1
        ]
    ]
];

&existingOverlayId = 1;

$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays/' . existingOverlayId . '?command=EDIT';

$curl = curl_init();

curl_setopt($curl, CURLOPT_PUT, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data)
]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, 'someSecretUsername:someSecretPassword');
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {    

   my $data = {
       'overlayName' => MyOverlayName',
       'overlayBoxDefinitionList' => [
           {
               'boxTypeId' => 5,
               'startXPercent' => 5.798,
               'startYPercent' => 25.755,
               'documentPage' => 1,
               'boxProperties' => {
                   'fontSize' => 24,
                   'boxWidth' => 520.55,
                   'boxHeight' => 120.44,
                   'characterLimit' => 40
               }
           },
           {
               'boxTypeId' => 2,
               'startXPercent' => 71.336,
               'startYPercent' => 10.151,
               'documentPage' => 1
           }
       ]
   };

   $data = JSON::XS->new->utf8->encode ($data);

   my $existingOverlayId = 1;

   my $url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays/' . existingOverlayId . '?command=EDIT';

   my $req = HTTP::Request->new( 'PUT', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin

   data = {
       'overlayName' => MyOverlayName',
       'overlayBoxDefinitionList' => [
           {
               'boxTypeId' => 5,
               'startXPercent' => 5.798,
               'startYPercent' => 25.755,
               'documentPage' => 1,
               'boxProperties' => {
                   'fontSize' => 24,
                   'boxWidth' => 520.55,
                   'boxHeight' => 120.44,
                   'characterLimit' => 40
               }
           },
           {
               'boxTypeId' => 2,
               'startXPercent' => 71.336,
               'startYPercent' => 10.151,
               'documentPage' => 1
           }
       ]
   }

   c = Curl::Easy.new
   existingOverlayId = 1
   c.url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays/' + existingOverlayId + '?command=EDIT'
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_post(payload)

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

-Overlay Deletion

<?php

&existingOverlayId = 1;

$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays/' . existingOverlayId . '?command=DELETE';

$curl = curl_init();

curl_setopt($curl, CURLOPT_PUT, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: 0'
]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, 'someSecretUsername:someSecretPassword');
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

   $data = JSON::XS->new->utf8->encode ($data);

   my $existingOverlayId = 1;
   my $url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays/' . existingOverlayId . '?command=DELETE';

   my $req = HTTP::Request->new( 'PUT', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length(0);

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin

   c = Curl::Easy.new
   existingOverlayId = 1
   c.url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/overlays/' + existingOverlayId + '?command=DELETE'
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = 0
   payload = data.to_json

   c.headers = headers
   c.http_put()

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

-Send Signature Request with a PAYMENT_PORTAL component


<?php
   $roundTripList = [
      'rtName'=>'personalIdNumber',
      'rtValue'=>'1234abcd'
   ];

$portalPrePopulateVariables = [
    'firstName'  =>'firstName',
    'lastName'  =>'lastName',
    'emailAddress'  =>'my@my.com',
    'streetAddressOne'  =>'streetAddressOne',
    'streetAddressTwo'  =>'streetAddressTwo',
    'city'  =>'city',
    'country'  =>'US',
    'zip'  =>'84401',
    'state'  =>'UT',
    'zipPlusFour'  =>'1234',
    'phoneNumber'  =>'8017782224',
    'accountNumber'  =>'234134',
    'memo'  =>'memo',
    'paymentAmount'  =>'100.00',
    'roundTrip'  => $roundTripList
];

$componentData = [
    'portalUrl' => 'https://appdemo.pdcflow.com/1234',
    'portalPrePopulateVariables' => $portalPrePopulateVariables
];

$componentList = [
    'componentType' => 'PAYMENT_PORTAL',
    'data' => $componentData
];

$data = [
    'customMessage' => 'Thank you for buying!',
    'description' => 'Agreement for mortgage.',
    'emailAddress' => 'frontenduser@pdc4u.com',
    'firstName' => 'Adam',
    'lastName' => 'Test',
    'maxPinAttempts' => '2',
    'mobileNumber' => '7777777777',
    'pinDescription' => 'Last four of your social security number',
    'verificationPageHeader' => 'Text that will be displayed at the top of the verification page',
    'redirectLink' => 'https://www.pdcflow.com',
    'requestGeolocation' => 'true',
    'roundTripNVPS' => $roundTripList,
    'companyOverride' => [
        'companyName' => 'Our Child Company'
    ],
    'componentList' => [
        $componentList
    ],
    'document' => [
        'documentId' => '1',
        'overlayId' => ''
        //Specify to include an overlay
    ],
    'imageUpload' => [
        'imageUploadDescription' => 'Upload photo id',
        'imageUploadRequested' => 'true',
    ],
    'standaloneSignatureRequested' => 'true',
    'templateName' => 'SignatureOnly',
    'timeoutMinutes' => '4.5',
    'transactionOrigin' => 'EXT',
    'username' => 'someuser@pdc4u.com',
    'verificationPin' => '1235',
    'postbackUrl' => 'https://www.testpostbackaddress.com'
];

$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures';

$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data)
]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, 'someSecretUsername:someSecretPassword');
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);

-Send Signature Request with a FILE_UPLOAD component


<?php
$fileUploadList = [
  [
    'fileType' => 'IMAGE',
    'isRequired' => true,
    'description' => 'Upload the Front Image'
  ],
  [
    'fileType' => 'IMAGE',
    'isRequired' => false,
    'description' => 'Upload the Back Image'
  ],
  [
    'fileType' => 'PDF',
    'isRequired' => true,
    'description' => 'Upload the PDF Contract'
  ],
  [
    'fileType' => 'FILE',
    'isRequired' => false,
    'description' => 'Upload the Image or PDF'
  ]
];

$componentList = [
  'componentType' => 'FILE_UPLOAD',
  'data' => [
    'fileUploadList' => $fileUploadList
  ]
];

$data = [
  'firstName' => 'Adam',
  'lastName' => 'Test',
  'maxPinAttempts' => '2',
  'mobileNumber' => '7777777777',
  'emailAddress' => 'frontenduser@pdc4u.com',
  'customMessage' => 'Thank you for buying!',
  'description' => 'Agreement for mortgage.',
  'verificationPin' => '1235',
  'pinDescription' => 'Last four of your social security number',
  'verificationPageHeader' => 'Text that will be displayed at the top of the verification page',
  'redirectLink' => 'https://www.pdcflow.com',
  'requestGeolocation' => 'true',
  'standaloneSignatureRequested' => 'true',
  'templateName' => 'SignatureOnly',
  'timeoutMinutes' => '5',
  'transactionOrigin' => 'EXT',
  'username' => 'someuser@pdc4u.com',
  'componentList' => [
    $componentList
  ]
];

$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures';

$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
  'Content-Type: application/json',
  'Content-Length: ' . strlen($data)
]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, 'someSecretUsername:someSecretPassword');
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);

-Sample Patch Signature

<?php
$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/123456';

$patch = [
  'roundTripNVPS' => [
    [
      'rtName'=>'myName',
      'rtValue'=>'myValue'
    ]
   ]
];
$curl = curl_init();

curl_setopt($curl, CURLOPT_PATCH, 1);
$data = json_encode($patch, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_PATCHFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
  ]);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);

PATCH a PatchSignature object to update an existing Signature for a specific signatureId.


test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/{signatureId}
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/{signatureId}

-Signature Retrieval

<?php
$desiredSignatureId = 12;
$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/' . $desiredSignatureId;

$curl = curl_init();

curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $desiredSignatureId = '1';
   my $url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/$desiredSignatureId";

   my $req = HTTP::Request->new( 'GET', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin
   desiredSignatureId = '1'
   url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/#{desiredSignatureId}"

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

General signature retrieval will use this method. It will retrieve the details for a signature with the specified id.

Send an HTTP GET request to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/[signatureId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/[signatureId]

-Signature Report Retrieval

<?php
$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/search';

$reportParams = [
  'startDate' => '2017-01-01 00:00:00',
  'endDate' => '2017-01-31 23:59:59',
  'firstName' => 'John',
  'lastName' => 'Smith',
  'recordCount' => '1000',
  'reportType' => 'ALL',
  'documentId' => '12345',
  'usernameList' => [
    'demo@domain.com'
  ],
  'locationIdList' => [
    '123456',
    '246801'
  ],
  'searchRoundTripNVPList' => [
    [
      'rtName' => 'employee',
      'rtValueList' => [
        "admin@demo.com",
        "billing@demo.com"
      ]
    ],
    [
      'rtName' => 'purchaseOrderNumber',
      'rtValueList' => [
        "123456",
        "-1",
        "0"
      ]
    ]
  ]
];

$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$reportParams = json_encode($reportParams, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $reportParams);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($reportParams)
  ]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {

   $reportParams = {
     'startDate' => '2017-01-01 00:00:00',
     'endDate' => '2017-01-31 23:59:59',
     'firstName' => 'John',
     'lastName' => 'Smith',
     'recordCount' => '1000',
     'reportType' => 'ALL',
     'documentId' => '12345',
     'usernameList' => {
       'demo@domain.com'
     },
     'locationIdList' => {
       '123456',
       '246801'
     },
     'searchRoundTripNVPList' => [
       {
         'rtName' => 'employee',
         'rtValueList' => [
           "admin@demo.com",
           "billing@demo.com"
           ]
       },
       {
         'rtName' => 'purchaseOrderNumber',
         'rtValueList' => [
           "123456",
           "-1",
           "0"
         ]
       }
     ]
   };

   $reportParams = JSON::XS->new->utf8->encode ($reportParams);

   my $url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/search';

   my $req = HTTP::Request->new( 'POST', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($reportParams) );
   $req->content( $reportParams );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
     print "Success: " . $response->decoded_content;
   }
   else {
     die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

   $reportParams = {
     'startDate' => '2017-01-01 00:00:00',
     'endDate' => '2017-01-31 23:59:59',
     'firstName' => 'John',
     'lastName' => 'Smith',
     'recordCount' => '1000',
     'reportType' => 'ALL',
     'documentId' => '12345',
     'usernameList' => {
       'demo@domain.com'
     },
     'locationIdList' => {
       '123456',
       '246801'
     },
     'searchRoundTripNVPList' => [
       {
         'rtName' => 'employee',
         'rtValueList' => [
           "admin@demo.com",
           "billing@demo.com"
         ]
       },
       {
         'rtName' => 'purchaseOrderNumber',
         'rtValueList' => [
           "123456",
            "-1",
            "0"
         ]
       }
     ]
   };

   url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/search"

   c = Curl::Easy.new
   c.url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures'
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = reportParams.to_json.length
   payload = reportParams.to_json

   c.headers = headers
   c.http_post(payload)

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

General signature retrieval will use this method. It will retrieve a list of Signature objects filtered by desired SearchParameters.

Send an HTTP POST request with the desired SearchParameters to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/search
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/search

Send an HTTP GET request to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/[signatureId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/[signatureId]

<?php
$url = 'https://flowdemo.pdcflow.com/api/v2_0/signatures/summary';

$searchParameters = [
  'startDate' => 'YYYY-MM-dd HH:mm:ss',
  'columnGroupList' => [
    'month',
    'roundTripNVPS.employee'
  ],
  'searchRoundTripNVPList' => [
    [
      'rtName' => 'employee',
      'rtValueList' => [
        "admin@demo.com",
        "billing@demo.com"
      ]
    ]
  ] 
];

$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($searchParameters, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data),
  ]);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
    my $searchParameters = {
        'startDate' => 'YYYY-MM-dd HH:mm:ss',
        'columnGroupList' => [
            'month',
            'roundTripNVPS.employee'
        ],
        'searchRoundTripNVPList' => [
            {
                'rtName' => 'employee',
                'rtValueList' => [
                    "admin@demo.com",
                    "billing@demo.com"
                ]
            }
        ] 
    }

    $data = JSON::XS->new->utf8->encode ($searchParameters);
    my $url = 'https://flowdemo.pdcflow.com/api/v2_0/signatures/summary';

    my $req = HTTP::Request->new( 'POST', $url );
    $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
    $req->content_type('application/json');
    $req->content_length( length($data) );
    $req->content( $data );

    my $lwp = LWP::UserAgent->new;
    $lwp->timeout(30);
    my $response = $lwp->request( $req );

    if ( $response->is_success ) {
        print "Success: " . $response->decoded_content;
    }
    else {
        die $response->status_line . ": " . $response->decoded_content;
    }
};

if ( $@ ) {
  print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin

    searchParameters = {
        'startDate' => 'YYYY-MM-dd HH:mm:ss',
        'columnGroupList' => [
            'month',
            'roundTripNVPS.employee'
        ],
        'searchRoundTripNVPList' => [
            {
                'rtName' => 'employee',
                'rtValueList' => [
                    "admin@demo.com",
                    "billing@demo.com"
                ]
            }
        ]
    }

    c = Curl::Easy.new
    c.url = 'https://flowdemo.pdcflow.com/api/v2_0/signatures/summary'
    c.http_auth_types = :basic
    c.username = 'SomeSecretUsername'
    c.password = 'SomeSecretPassword'
    c.connect_timeout = 5
    c.timeout = 30
    c.verbose = true

    headers={}
    headers['Content-Type'] = 'application/json'
    headers['Content-Length'] = data.to_json.length
    payload = searchParameters.to_json

    c.headers = headers
    c.http_post(payload)

    puts JSON.parse c.body_str

    if c.response_code == 200 then
        puts "Success " + c.status
    else
        puts "Error " + c.status
    end
rescue
    puts "Caught: #$!\n"
end

POST FlowSummarySearchParameters for a FlowSummarySearch object which contains Flow Summary Totals.


Test URL:
https://flowdemo.pdcflow.com/api/v2_0/signatures/summary
Live URL:
https://flow.pdcflow.com/api/v2_0/signatures/summary

-Signature Modification

<?php
$idOfSignatureToModify = 1;
$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/' . $idOfSignatureToModify;

$data = [
  'signatureId' => $idOfSignatureToModify,
  'modificationCode' => 'CLOSE',
  'username' => 'frontenduser@pdc4u.com'
];

$curl = curl_init();

curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data)
  ]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting
use File::Slurp;
use MIME::Base64;

eval {
   my $idOfSignatureToModify = 1;
   my $url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/$idOfSignatureToModify";

   my $data = {
      'signatureId' => $idOfSignatureToModify,
      'modificationCode' => 'CLOSE',
      'username' => 'someuser@pdc4u.com'
   };
   $data = JSON::XS->new->utf8->encode ($data);

   my $req = HTTP::Request->new( 'PUT', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin
#   idOfSignatureToModify = 1;
   idOfSignatureToModify = 2560;
   url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/#{idOfSignatureToModify}"

   data = {
      'signatureId' => idOfSignatureToModify,
      'modificationCode' => 'CLOSE',
      'username' => 'someuser@pdc4u.com'
   }


   c = Curl::Easy.new
   c.url = url
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers = {}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_put(payload)

   #puts JSON.parse c.body_str
   puts c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

General signature modification will use this method. It will modify an existing signature request. Currently, only “CLOSE” is supported.

Send an HTTP PUT request, with required data, to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/signatures/[signatureId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/signatures/[signatureId]

-Document Upload

<?php
$data = [
  'documentName' => 'HR_Document',
  'documentBase64String' => 'base64encodedString'
];

$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents';

$curl = curl_init();

curl_setopt($curl, CURLOPT_POST, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data)
  ]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting
use File::Slurp;
use MIME::Base64;

eval {
   # read and encode pdf to upload
   my $pdfDocument = 'mydoc.pdf';
   my $pdfContents = read_file( $pdfDocument );
   my $documentData = encode_base64($pdfContents, ""); # encode without newlines

   my $data = {
      'documentName' => 'HR_Document',
      'documentBase64String' => $documentData
   };
   $data = JSON::XS->new->utf8->encode ($data);

   my $url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents';

   my $req = HTTP::Request->new( 'POST', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin
   # read and encode pdf to upload
   pdfDocument = 'mydoc.pdf'
   file = File.open(pdfDocument, "rb")
   contents = file.read
   file.close
   documentData = Base64.strict_encode64(contents) # encodes without newlines

   data = {
      'documentName' => 'HR_Document',
      'documentBase64String' => documentData
   }

   c = Curl::Easy.new
   c.url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents';
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_post(payload)

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

General document upload requests will use this method. It will upload a document and return a documentId to be used when sending a signature request.

Send an HTTP POST request, with required data, to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/documents

-Document Retrieval

<?php
$desiredDocumentId = 12;
$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents/' . $desiredDocumentId;

$curl = curl_init();

curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $desiredDocumentId = '1';
   my $url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents/$desiredDocumentId";

   my $req = HTTP::Request->new( 'GET', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin
   desiredDocumentId = '1'
   url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents/#{desiredDocumentId}"

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

General document retrieval will use this method. It will retrieve the details for an uploaded document with the specified id.

Send an HTTP GET request to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/documents/[documentId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/documents/[documentId]

-ImageUpload Retrieval

<?php
$desiredImageUploadId = 12;
$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/imageUploads/' . $desiredImageUploadId;

$curl = curl_init();

curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $desiredImageUploadId = '1';
   my $url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/imageUploads/$desiredImageUploadId";

   my $req = HTTP::Request->new( 'GET', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin
   desiredImageUploadId = '1'
   url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/imageUploads/#{desiredImageUploadId}"

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

General image upload retrieval will use this method. It will retrieve the details for a single image, uploaded by the client, for the given image upload id.

Send an HTTP GET request to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/imageUploads/[imageUploadId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/imageUploads/[imageUploadId]

A list of all images uploaded by the client may also be obtained by sending the related signature ID in an HTTP GET request to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/imageUploads/allUploads/[signatureId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/imageUploads/allUploads/[signatureId]

An image upload may also be received by passing the related signature ID in an HTTP GET request to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/imageUploads?signatureId=[signatureId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/imageUploads?signatureId=[signatureId]

-Transaction Report Retrieval

<?php
$desiredSignatureId = 12;
$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/transactionReports/' . $desiredSignatureId . '?reportType=FULL';

$curl = curl_init();

curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting

eval {
   my $desiredSignatureId = 1;
   my $url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/transactionReports/$desiredSignatureId?reportType=RECEIPT";

   my $req = HTTP::Request->new( 'GET', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );

   my $lwp = LWP::UserAgent->new;
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print "Success: " . $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'

begin
   desiredSignatureId = '1'
   url = "https://flowdemo.pdcflow.com/FlowService/api/v2_0/transactionReports/#{desiredSignatureId}?reportType=FULL"

   c = Curl::Easy.new( url )
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true
   c.perform

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

General transaction report retrieval will use this method. It will create and retrieve a detailed report for a signature transaction.

Send an HTTP GET request to:
test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/transactionReports/[signatureId]
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/transactionReports/[signatureId]

-Migrate Signature Account Directives

<?php
$data = [
  'oldAccountDirective' => '123-1',
  'newAccountDirective' => '123-2'
];

$url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/migrations/accountdirectives';

$curl = curl_init();

curl_setopt($curl, CURLOPT_PATCH, 1);
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
curl_setopt($curl, CURLOPT_PATCHFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data)
  ]);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "someSecretUsername:someSecretPassword");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);  //num seconds to try connecting
curl_setopt($curl, CURLOPT_TIMEOUT, 30); //max number of seconds to allow execution

$result = curl_exec($curl);

$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

// View response
print_r(json_decode($result, true));

if($statusCode == '200') {
  echo $result;
}
else {
  echo "Error #:" . $statusCode;
}
curl_close($curl);
#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Request::Common;
use JSON::XS;
use IO::Socket::SSL qw(debug3); # verbose for troubleshooting
use File::Slurp;
use MIME::Base64;

eval {

   my $data = {
      'oldAccountDirective' => '123-1',
      'newAccountDirective' => '123-2'
   };
   $data = JSON::XS->new->utf8->encode ($data);

   my $url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/migrations/accountdirectives';

   my $req = HTTP::Request->new( 'PATCH', $url );
   $req->authorization_basic( 'SomeSecretUsername', 'SomeSecretPassword' );
   $req->content_type('application/json');
   $req->content_length( length($data) );
   $req->content( $data );

   my $lwp = LWP::UserAgent->new;
   $lwp->timeout(30);
   my $response = $lwp->request( $req );

   if ( $response->is_success ) {
      print $response->decoded_content;
   }
   else {
      die $response->status_line . ": " . $response->decoded_content;
   }
};
if ( $@ ) {
   print "Error: $@\n";
}
#!/usr/bin/ruby

require 'curl'
require 'curb'
require 'json'
require 'base64'

begin

   data = {
      'oldAccountDirective' => '123-1',
      'newAccountDirective' => '123-2'
   }

   c = Curl::Easy.new
   c.url = 'https://flowdemo.pdcflow.com/FlowService/api/v2_0/migrations/accountdirectives';
   c.http_auth_types = :basic
   c.username = 'SomeSecretUsername'
   c.password = 'SomeSecretPassword'
   c.connect_timeout = 5
   c.timeout = 30
   c.verbose = true

   headers={}
   headers['Content-Type'] = 'application/json'
   headers['Content-Length'] = data.to_json.length
   payload = data.to_json

   c.headers = headers
   c.http_patch(payload)

   puts JSON.parse c.body_str

   if c.response_code == 200 then
      puts "Success " + c.status
   else
      puts "Error " + c.status
   end
rescue
   puts "Caught: #$!\n"
end

Send an HTTP PATCH request to: test endpoint: https://flowdemo.pdcflow.com/FlowService/api/v2_0/migrations/accountdirectives
live endpoint: https://flow.pdcflow.com/FlowService/api/v2_0/migrations/accountdirectives