NAV
curl ruby javascript

Introduction

GoCanvas uses a standard REST API to provide access to a number of useful features. Users can manage Forms, create Submissions, retrieve Reports, and much more.

Looking for a no-code solution?

Check GoCanvas' Integrations for over 1,000 pre-built connectors to popular cloud services.

Base URL

All URLs referenced in the documentation have the following base: https://www.gocanvas.com/api/v3/

Overview

API Versioning

GoCanvas API versioning follows semantic versioning, treating the published number as a "major" release. As such, best efforts will be made to introduce changes in a reverse-compatible way. Should a "major" change be needed to improve the API, we would announce an API v4 and make a determination at that point if v3 needs to be deprecated with ample warning to allow customers to migrate to a newer version.

Authentication: Basic

To authorize a request, supply a username and password

curl -u "api.user@example.com:supersecretpassword" \
  "https://www.gocanvas.com/api/v3/[ENDPOINT]"
username = "api.user@example.com"
password = "supersecretpassword"
endpoint = "https://www.gocanvas.com/api/v3/[ENDPOINT]?username=#{username}&password=#{password}"

uri = URI.parse(endpoint)
req = Net::HTTP::Get.new(endpoint)
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  http.request(req)
end

const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/[ENDPOINT]", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
})
  .then(response => response.json())
  .then(data => console.log(data))

GoCanvas supports HTTP basic auth to turn your existing username and password into API access: simply include these parameters with your requests.

Parameter Description
username username for the GoCanvas website
password password for the GoCanvas website

Authentication: Bearer

GoCanvas supports OAuth 2.0 authentication to retrieve a short-lived token for API access. This token can then be passed in the Authorization HTTP header as a Bearer token to authenticate requests.

To use Bearer authentication, you must first create an OAuth application in your profile. GoCanvas offers two OAuth 2.0 flows:

  1. Client Credentials Flow: For confidential client applications (server-to-server) that can securely store client secrets.
  2. Authorization Code with PKCE: For public client applications like mobile apps or SPAs; refresh tokens are also available for this flow.

Client Credentials Flow

The Client Credentials flow is ideal for confidential client applications (server-side) where you can securely store a client secret.

Client Credentials Flow Example

TOKEN_RESPONSE=$(curl -X POST "https://www.gocanvas.com/api/v3/oauth/token" \
  -d "grant_type=client_credentials" \
  -d "client_id=your-client-id" \
  -d "client_secret=your-client-secret" \
  -d "scope=api")

TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.access_token')

# Use the token in the Authorization header for future requests
curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  "https://www.gocanvas.com/api/v3/[ENDPOINT]"

client_id = "your-client-id"
client_secret = "your-client-secret"
scope = "api"

uri = "https://www.gocanvas.com/api/v3/oauth/token"

uri = URI.parse(uri)
req = Net::HTTP::Post.new(uri)
req.set_form_data(
  "grant_type": "client_credentials",
  "client_id": client_id,
  "client_secret": client_secret,
  "scope": scope
)

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

# Use the token from the response in the Authorization header for future requests
token = JSON.parse(response.body)["access_token"]

# Use the token in the Authorization header for future requests
endpoint = "https://www.gocanvas.com/api/v3/[ENDPOINT]"
req = Net::HTTP::Get.new(endpoint)
req["Authorization"] = "Bearer #{token}"
http.request(req)

const client_id = "your-client-id";
const client_secret = "your-client-secret";
const scope = "api";
const data = {
  grant_type: "client_credentials",
  client_id: client_id,
  client_secret: client_secret,
  scope: scope,
};

const tokenResponse = await fetch("https://www.gocanvas.com/api/v3/oauth/token", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
});

const tokenData = await tokenResponse.json();
const token = tokenData.access_token;

// Use the token in the Authorization header for future requests
const endpoint = "https://www.gocanvas.com/api/v3/[ENDPOINT]";
fetch(endpoint, {
  method: "GET",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
}).then((response) => {
  console.log(response);
});

OAuth Token Response

{
  "access_token": "30puVebCmI7wbVjIQPt1KIYE81voxKdkKZwSaCWRiZM",
  "token_type": "Bearer",
  "expires_in": 7200,
  "scope": "api",
  "created_at": 1733346054
}

HTTP Request

POST https://www.gocanvas.com/api/v3/oauth/token

Request Body Parameters

Parameter Type Description
grant_type enum Using client_credentials
client_id string The client ID for your application. Available in your API Settings page.
client_secret string The client secret for your application. Downloaded when you create the OAuth application.
scope string The scope for the token. Use api for API access.

Authorization Code Flow with PKCE

The Authorization Code flow with PKCE (Proof Key for Code Exchange) is designed for public client applications where storing a client secret isn't secure. The endpoints for this flow are:

HTTP Request

POST https://www.gocanvas.com/api/v3/oauth/token

Request Body Parameters

Parameter Type Description
grant_type enum Using authorization_code
client_id string The client ID for your application. Available in your API Settings page.
code string The authorization code received from the authorize endpoint
code_verifier string The original code verifier generated for PKCE
redirect_uri string The URI to redirect users to after authorization.

OAuth Token Response (Authorization Code Flow)

{
  "access_token": "30puVebCmI7wbVjIQPt1KIYE81voxKdkKZwSaCWRiZM",
  "token_type": "Bearer",
  "expires_in": 7200,
  "refresh_token": "jJt6HS_WmN80kqKXI7ycWRUiQAgyuCHwIkGI0wdpWmw",
  "scope": "api",
  "created_at": 1733346054
}

Using Refresh Tokens (Optional)

When the access token expires, use the refresh token to get a new one without user interaction. Most OAuth libraries handle this automatically.

Request Body Parameters for Refresh Tokens

Parameter Type Description
grant_type enum Using refresh_token
client_id string The client ID for your application. Available in your API Settings page.
refresh_token string The refresh token received when the access token was issued

Using the Access Token

Regardless of which flow you use, once you have an access token, include it in API requests:

curl https://www.gocanvas.com/api/v3/some_endpoint \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response Parameters

Parameter Type Description
access_token string The access token for the request
token_type enum The type of token. Will be Bearer
expires_in integer The number of seconds until the token expires
refresh_token string (Only for authorization code flow) Token used to obtain new access tokens
scope string The scope(s) for the token
created_at integer The timestamp when the token was created

For more information on implementing the authorization code flow with PKCE, see the OAuth 2.0 PKCE documentation and the RFC 7636 specification.

Errors

The GoCanvas API uses the following error codes:

422 ERROR RESPONSE

{
  "errors": [
      "Invalid department ID provided"
  ]
}
Error Code Meaning Description
400 Bad Request Your request is invalid
401 Unauthorized Your API key is wrong
403 Forbidden The response requested is hidden for administrators only
404 Not Found The specified response could not be found
422 Unprocessable Entity The request was well-formed but was unable to be followed due to validation errors
429 Too Many Requests You've hit the rate limit. Please wait a bit and try again. See Rate Limits for more information
500 Internal Server Error We had a problem with our server. Please try again later
503 Service Unavailable We're temporarily offline for maintenance. Please try again later

Pagination

The GoCanvas API uses pagination to limit the number of results returned on "list" methods. The default number of results returned is 100, unless otherwise specified.

Pagination information is included in the response headers, including a RFC-8288 compliant link header.

RESPONSE

link:            <https://www.gocanvas.com/api/v3/forms?page=1>; rel="first",
                 <https://www.gocanvas.com/api/v3/forms?page=2>; rel="next",
                 <https://www.gocanvas.com/api/v3/forms?page=5>; rel="last"
current_page:    1
page_items:      100
total_count:     500
total_pages:     5
Header Description
link A link to the next, previous, first, and last pages
current-page The current page number
page-items The number of results per page
total-count The total number of results available
total-pages The total number of pages available

Rate Limits

The GoCanvas API uses rate limiting to prevent abuse and ensure system reliability for all users. An HTTP error code of 429 Too Many Requests is used to indicate the current request was over the rate limit. In order to avoid 429 errors, inspect the Response Headers detailed below.

Best Practices

In order to slow down requests API users should ensure that they are rate limiting on their own servers. Calling the API in loops should only be done with a built in delay. Calling the API with multiple concurrent requests may also result in hitting the rate limit, so concurrency and multithreading of requests should be avoided.

If you receive a rate limit error, you should stop making requests temporarily according to these guidelines:

429 RESPONSE HEADERS

RateLimit-Limit           10
RateLimit-Remaining       0
RateLimit-Reset           1480000000
Header Meaning
RateLimit-Limit Number of requests allowed for the given request
RateLimit-Remaining Number of requests remaining for the given request
RateLimit-Reset Time at which the rate limit will reset (in UTC epoch seconds)

Customer

Defines a customer's contact information and can either be an individual or a business entity. A Customer is optionally associated with a Site.

The Customer object

EXAMPLE

{
  "id": 10,
  "type": "customer",
  "customer_type": "individual",
  "business_name": null,
  "contact_role": null,
  "contact_first_name": "Ben",
  "contact_last_name": "Jackson",
  "contact_email": "ben.jackson@example.com",
  "contact_phone": "5555555555",
  "contact_preference": null,
  "notes": null,
  "default_site_id": 1,
  "code": "NEW00001"
}

A Customer requires a customer_type to be created. If customer_type is individual, you need to provide contact_first_name and contact_last_name. If customer_type is business, you need to provide business_name.

Customers and Sites

A Customer can be associated with many Sites. By passing a default_site_id and/or an array of site_ids in the PATCH request, you can attach Sites to the Customer.

Customers can have multiple Sites associated with them. The first Site associated with the Customer is considered the Primary Site. Any sites added after the first site are considered "Additional Sites".

List all Customers

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/customers
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/customers")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

customers_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/customers", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(customers => console.log(customers));

Users can view a list of all the Customers associated with the company.

RESPONSE

[
  {
    "id": 10,
    "type": "customer",
    "customer_type": "individual",
    "business_name": null,
    "contact_role": null,
    "contact_first_name": "Ben",
    "contact_last_name": "Jackson",
    "contact_email": "ben.jackson@example.com",
    "contact_phone": "5555555555",
    "contact_preference": null,
    "notes": null,
    "default_site_id": 1,
    "code": "NEW00001"
  },
  {
    "id": 11,
    "type": "customer",
    "customer_type": "business",
    "business_name": "Chichago Inc",
    "contact_role": null,
    "contact_first_name": "Jessica",
    "contact_last_name": "Nixon",
    "contact_email": "jessica.nixon@example.com",
    "contact_phone": "4444444444",
    "contact_preference": null,
    "notes": null,
    "default_site_id": null,
    "code": "NEW00002"
  },
  {
    "id": 12,
    "type": "customer",
    "customer_type": "individual",
    "business_name": null,
    "contact_role": null,
    "contact_first_name": "Sam",
    "contact_last_name": "Johnson",
    "contact_email": "sam.johnson@example.com",
    "contact_phone": "3333333333",
    "contact_preference": null,
    "notes": null,
    "default_site_id": 3,
    "code": "NEW00003"
  }
]

HTTP Request

GET https://www.gocanvas.com/api/v3/customers

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1

Retrieve a Customer

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/customers/10
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/customers/10")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

customer_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/customers/10", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(customer => console.log(customer));

Users can retrieve a Customer by its ID.

HTTP Request

GET https://www.gocanvas.com/api/v3/customers/10

RESPONSE

{
  "id": 10,
  "type": "customer",
  "customer_type": "individual",
  "business_name": null,
  "contact_role": null,
  "contact_first_name": "Ben",
  "contact_last_name": "Jackson",
  "contact_email": "ben.jackson@example.com",
  "contact_phone": "5555555555",
  "contact_preference": null,
  "notes": null,
  "default_site_id": 1,
  "code": "NEW00001"
}

Response Parameters

Parameter Type Description
id integer The identifier for this exact Customer
type string The type of the Customer, always customer
customer_type enum The type of the Customer. Can be individual or business
business_name string The name of the business, if the customer_type is a business
contact_role string The role of the contact person for the Customer
contact_first_name string The first name of the contact person for the Customer
contact_last_name string The last name of the contact person for the Customer
contact_email string The email address of the contact person for the Customer
contact_phone string The phone number of the contact person for the Customer
contact_preference string The preferred method of contact for the Customer
notes string A longer string value to describe the Customer
default_site_id integer The ID of the default site associated with the Customer
code string An alpha numeric code to uniquely identify the Customer

Create a Customer

To create a new Customer, the POST body can be sent as JSON. The customer_type field is required. If customer_type is individual, you must also provide contact_first_name and contact_last_name. If customer_type is business, you must also provide business_name.

BODY='{
  "customer_type": "business",
  "business_name": "LLC Renovation",
  "contact_first_name": "Sean",
  "contact_last_name": "Mitchel",
  "contact_email": "sean.mitchel@example.com",
  "contact_phone": "3334445555",
  "code": "NEW00001",
  "site_id": 7
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/customers
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "customer_type": "business",
  "business_name": "LLC Renovation",
  "contact_first_name": "Sean",
  "contact_last_name": "Mitchel",
  "contact_email": "sean.mitchel@example.com",
  "contact_phone": "3334445555",
  "code": "NEW00001",
  "site_id": 7
}

uri = URI("https://www.gocanvas.com/api/v3/customers")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

customer_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "customer_type": "business",
  "business_name": "LLC Renovation",
  "contact_first_name": "Sean",
  "contact_last_name": "Mitchel",
  "contact_email": "sean.mitchel@example.com",
  "contact_phone": "3334445555",
  "code": "NEW00001",
  "site_id": 7
};

fetch("https://www.gocanvas.com/api/v3/customers", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(customer => console.log(customer));

RESPONSE

{
  "id": 14,
  "type": "customer",
  "customer_type": "business",
  "business_name": "LLC Renovation",
  "contact_role": null,
  "contact_first_name": "Sean",
  "contact_last_name": "Mitchel",
  "contact_email": "sean.mitchel@example.com",
  "contact_phone": "3334445555",
  "contact_preference": null,
  "notes": null,
  "default_site_id": 7,
  "code": "NEW00001"
}

HTTP Request

POST https://www.gocanvas.com/api/v3/customers

Request Body Parameters

Parameter Type Description
customer_type* enum The type of the Customer. Can be individual or business
business_name** string The name of the business, if the customer_type is a business
contact_role string The role of the contact person for the Customer
contact_first_name** string The first name of the contact person for the Customer
contact_last_name** string The last name of the contact person for the Customer
contact_email string The email address of the contact person for the Customer
contact_phone string The phone number of the contact person for the Customer
contact_preference string The preferred method of contact for the Customer
notes string A longer string value to describe the Customer
code string An alpha numeric code to uniquely identify the Customer

* required field

** If customer_type is individual, you need to provide contact_first_name and contact_last_name. If customer_type is business, you need to provide business_name.

Update a Customer

To update an existing Customer, the PATCH request body can be sent as JSON.

BODY='{
  "default_site_id": 12,
  "notes": "Unit renovation",
  "site_ids": [10, 11, 12]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X PATCH \
  -d $BODY \
  https://www.gocanvas.com/api/v3/customers/14
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "default_site_id": 12,
  "notes": "Unit renovation",
  "site_ids": [10, 11, 12]
}

uri = URI("https://www.gocanvas.com/api/v3/customers/14")

json_request_body = request_body.to_json
req = Net::HTTP::Patch.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

customer_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "default_site_id": 12,
  "notes": "Unit renovation",
  "site_ids": [10, 11, 12]
};

fetch("https://www.gocanvas.com/api/v3/customers/14", {
  method: "PATCH",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(customer => console.log(customer));

RESPONSE

{
  "message": "Customer updated successfully"
}

HTTP Request

PATCH https://www.gocanvas.com/api/v3/customers/14

Request Body Parameters

Parameter Type Description
customer_type* enum The type of the Customer. Can be individual or business
business_name** string The name of the business, if the customer_type is a business
contact_role string The role of the contact person for the Customer
contact_first_name** string The first name of the contact person for the Customer
contact_last_name** string The last name of the contact person for the Customer
contact_email string The email address of the contact person for the Customer
contact_phone string The phone number of the contact person for the Customer
contact_preference string The preferred method of contact for the Customer
notes string A longer string value to describe the Customer
default_site_id integer The ID of the default site associated with the Customer. When multiple site_ids are provided this field denotes the Primary Site.
code string An alpha numeric code to uniquely identify the Customer
site_ids array Sites IDs for adding Sites to the Customer. When more than one Site is provided, the first will be used unless a default_site_id is specified

* required field

** If customer_type is individual, you need to provide contact_first_name and contact_last_name. If customer_type is business, you need to provide business_name.

Delete a Customer

A Customer can be deleted with a DELETE request.

By default, the DELETE request will soft-delete the Customer, which preserves the Customer data but hides it from the web views. To permanently delete a Customer, use the hard_delete=true parameter, e.g. DELETE https://www.gocanvas.com/api/v3/customers/14?hard_delete=true.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/customers/14
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/customers/14")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

customer_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/customers/14", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(customer => console.log(customer));

RESPONSE

{
  "message": "Customer 14 has been soft deleted successfully"
}

HTTP Request

DELETE https://www.gocanvas.com/api/v3/customers/14

Request Parameters

Parameter Type Description
hard_delete* boolean Will hard delete the Customer record when set to true

* This is an optional URL parameter. If not provided, the Customer will be soft deleted.

Department

A Department represents an organizational unit within a Company. Users can be assigned to one or multiple Departments. Forms created in one Department can be shared with another.

The Department object

EXAMPLE

{
  "id": 114,
  "type": "department",
  "name": "My New Department",
  "description": "This is a new department",
  "created_at": "2023-06-02 13:43:08 UTC"
}

Property Type Description
id integer The unique Department id
type string The type of object
name string A short string value for name of a new Department
description string A longer string value describing a new Department
created_at date A timestamp of when the Department was originally created

List all Departments

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/departments
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/departments")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

departments_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/departments", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(departments => console.log(departments));

Users can view a list of all the Departments associated with their Company.

HTTP Request

GET https://www.gocanvas.com/api/v3/departments

RESPONSE

[
  {
    "id": -1,
    "type": "department",
    "name": "All",
    "description": "All",
    "created_at": null
  },
  {
    "id": 111,
    "type": "department",
    "name": "First Department",
    "description": "My first department",
    "created_at": "2023-05-31 15:34:47 UTC"
  },
  {
    "id": 112,
    "type": "department",
    "name": "Second Department",
    "description": "A second department",
    "created_at": "2023-05-31 16:24:28 UTC"
  },
  {
    "id": 113,
    "type": "department",
    "name": "Third Department",
    "description": "My third department",
    "created_at": "2023-05-31 16:27:30 UTC"
  }
]

Create a Department

BODY='{
  name: "My New Department",
  description: "This is a new Department"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/departments
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  name: "My New Department",
  description: "This is a new Department"
}

uri = URI("https://www.gocanvas.com/api/v3/departments")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

department_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  name: "My New Department",
  description: "This is a new Department"
};

fetch("https://www.gocanvas.com/api/v3/departments", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(department => console.log(department));

Users have the ability to create a Department to a specified Company with a name and a description.

HTTP Request

POST https://www.gocanvas.com/api/v3/departments

RESPONSE

{
  "id": 114,
  "type": "department",
  "name": "My New Department",
  "description": "This is a new department",
  "created_at": "2023-06-02 13:43:08 UTC"
}

Request Body Parameters

Parameter Type Description
name string A short string value for name of a new Department
description string A longer string value describing a new Department

List all Department Users

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/departments/1999/users
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/departments/1999/users")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

users_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/departments/1999/users", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(users => console.log(users));

Users can view a list of all the Users within a Department.

HTTP Request

GET https://www.gocanvas.com/api/v3/departments/1999/users

RESPONSE

[
  {
    "type": "department_user",
    "user": {
      "id": 5486,
      "first_name": "Jane",
      "last_name": "Doe",
      "email": "jane.doe@gocanvas.com",
      "enabled": true
    },
    "department_role": "department_user",
    "created_at": "2022-09-13 17:02:49 UTC",
    "updated_at": "2022-09-13 17:02:49 UTC"
  },
  {
    "type": "department_user",
    "user": {
      "id": 5490,
      "first_name": "Smith",
      "last_name": "Kane",
      "email": "smith.kane@gocanvas.com",
      "enabled": false
    },
    "department_role": "department_admin",
    "created_at": "2022-09-13 17:02:49 UTC",
    "updated_at": "2022-09-13 17:02:49 UTC"
  }
]

Add a User to a Department

BODY='{
  "user_id": 5491,
  "department_role": "department_user"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/departments/1999/users
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "user_id": 5491,
  "department_role": "department_user"
}

uri = URI("https://www.gocanvas.com/api/v3/departments/1999/users")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

user_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "user_id": 5491,
  "department_role": "department_user"
};

fetch("https://www.gocanvas.com/api/v3/departments/1999/users", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(user => console.log(user));

To add an existing User to a Department you'll need to pass a valid user_id and a department_role giving the User specific rights within a Department.

HTTP Request

POST https://www.gocanvas.com/api/v3/departments/1999/users

Request Body Parameters

Parameter Type Description Options
user_id integer The id of the User to add
department_role string A string matching a valid departmental role department_admin department_reporter department_user department_designer department_dispatcher

Response

RESPONSE

{
  "type": "department_user",
  "department_role": "department_user",
  "created_at": "2023-05-31 14:36:04 UTC",
  "updated_at": "2023-05-31 14:36:04 UTC",
  "user_id": 5491,
  "department_id": 1999
}

Parameter Type Description
type string The type of object
department_role string A string value for user's role in the Department
user_id integer The User that was added to the Department
department_id integer The Department the User joined/had their role updated in
already_existed* boolean If the User was already in the Department

* Only returned if the User was already part of the Department

Dispatch

A Dispatch is a pre-populated set of responses to a Form that will become a Submission once the dispatched user completes the Form. Dispatches also have additional capabilities such as scheduling and notifications. Dispatches will closely resemble Submissions.

The Dispatch object

EXAMPLE

{
  "id": 194780,
  "type": "dispatch_item",
  "form_id": 346103,
  "user_id": 840365,
  "department_id": 11942,
  "customer_id": null,
  "project_id": null,
  "site_id": null,
  "submission_id": null,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "status": "assigned",
  "scheduled_at": null,
  "scheduled_end": null,
  "sent_at": null,
  "completed_at": null,
  "deleted_at": null,
  "send_calendar_invite": false,
  "reminder_interval": null,
  "created_at": "2024-11-11 21:09:02 UTC",
  "responses": [
    { "id": 7894001, "type": "response", "entry_id": 4506586, "value": "Jane" },
    { "id": 7894002, "type": "response", "entry_id": 4506587, "value": "Doe" },
    { "id": 7894003, "type": "response", "entry_id": 4506588, "value": "Main St" },
    { "id": 7894004, "type": "response", "entry_id": 4506589, "value": "Boca Raton" },
    { "id": 7894005, "type": "response", "entry_id": 4506590, "value": "FL" },
    { "id": 7894006, "type": "response", "entry_id": 4506591, "value": "23456" },
    { "id": 7894007, "type": "response", "entry_id": 4506592, "value": "USA" },
    { "id": 7894008, "type": "response", "entry_id": 4506593, "value": "222-333-4444" }
  ]
}

Dispatches must reference a Form. Responses within a Dispatch align to those within a Submission.

For retrieving a form's entries used for Creating a Dispatch, see the minimal Form format documentation.

List all Dispatches

Users can retrieve a list of all Dispatches that they have access to. Required parameters are user_id, department_id, or form_id.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/dispatches
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/dispatches")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

dispatches_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/dispatches", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(dispatches => console.log(dispatches));

RESPONSE

[
  {
    "id": 194780,
    "type": "dispatch_item",
    "form_id": 346103,
    "user_id": 840365,
    "department_id": 11942,
    "customer_id": null,
    "project_id": null,
    "site_id": null,
    "submission_id": null,
    "name": "Repair request",
    "description": "123 Main St Service Request",
    "status": "assigned",
    "scheduled_at": "2024-10-01T08:00:00Z",
    "scheduled_end": "2024-12-01T12:00:00Z",
    "sent_at": null,
    "completed_at": null,
    "deleted_at": null,
    "send_calendar_invite": true,
    "reminder_interval": 60,
    "created_at": "2024-11-11T21:09:02Z"
  },
  {
    "id": 194781,
    "type": "dispatch_item",
    "form_id": 346103,
    "user_id": 840365,
    "department_id": 11942,
    "customer_id": null,
    "project_id": null,
    "site_id": null,
    "submission_id": null,
    "name": "Fence repair request",
    "description": "123 Main St Service Request",
    "status": "assigned",
    "scheduled_at": "2024-12-03T08:00:00Z",
    "scheduled_end": "2024-12-03T10:00:00Z",
    "sent_at": null,
    "completed_at": null,
    "deleted_at": null,
    "send_calendar_invite": true,
    "reminder_interval": 60,
    "created_at": "2024-11-11T21:09:02Z"
  },
  {
    "id": 194782,
    "type": "dispatch_item",
    "form_id": 346103,
    "user_id": 840365,
    "department_id": 11942,
    "customer_id": null,
    "project_id": null,
    "site_id": null,
    "submission_id": null,
    "name": "Tree trimming request",
    "description": "123 Main St Service Request",
    "status": "assigned",
    "scheduled_at": "2024-12-06T08:00:00Z",
    "scheduled_end": "2024-12-06T12:00:00Z",
    "sent_at": null,
    "completed_at": null,
    "deleted_at": null,
    "send_calendar_invite": true,
    "reminder_interval": 60,
    "created_at": "2024-11-11T21:09:02Z"
  }

]

HTTP Request

GET https://www.gocanvas.com/api/v3/dispatches

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1
user_id* integer (optional) The identifier for the User assigned the Dispatch
department_id* integer (optional) The identifier for the Department associated with the Dispatch
form_id* integer (optional) The identifier for the Form associated with Dispatch
status enum (optional) The status of the Dispatch. Can be unassigned,assigned, or received
start_date** string (optional) A DateTime value for the beginning bounds to filter the Dispatches' created_at
end_date** string (optional) A DateTime value for the ending bounds to filter the Dispaches' created_at
scheduled_start_date** string (optional) A DateTime value for the beginning bounds to filter the Dispatches' scheduled_at
scheduled_end_date** string (optional) A DateTime value for the ending bounds to filter the Dispaches' scheduled_end

* Either user_id, department_id, or form_id must be provided.

** start_date, end_date, scheduled_start_date and scheduled_end_date must be in the ISO-8601 format, e.g. 2024-01-30 or 2024-01-30T23:59:59 or 2024-01-30T23:59:59-04:00

Retrieve a Dispatch

Users can retrieve a Dispatch by its ID.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/dispatches/194780
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/dispatches/194780")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

dispatch_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/dispatches/194780", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(dispatch => console.log(dispatch));

RESPONSE

{
  "id": 194780,
  "type": "dispatch_item",
  "form_id": 346103,
  "user_id": 840365,
  "department_id": 11942,
  "customer_id": null,
  "project_id": null,
  "site_id": null,
  "submission_id": null,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "status": "assigned",
  "scheduled_at": "2024-12-01 08:00:00 UTC",
  "scheduled_end": "2024-12-01 12:00:00 UTC",
  "sent_at": null,
  "completed_at": null,
  "deleted_at": null,
  "send_calendar_invite": true,
  "reminder_interval": 60,
  "created_at": "2024-11-11 21:09:02 UTC",
  "responses": [
    { "id": 7894001, "type": "response", "entry_id": 4506586, "value": "Jane" },
    { "id": 7894002, "type": "response", "entry_id": 4506587, "value": "Doe" },
    { "id": 7894003, "type": "response", "entry_id": 4506588, "value": "Main St" },
    { "id": 7894004, "type": "response", "entry_id": 4506589, "value": "Boca Raton" },
    { "id": 7894005, "type": "response", "entry_id": 4506590, "value": "FL" },
    { "id": 7894006, "type": "response", "entry_id": 4506591, "value": "23456" },
    { "id": 7894007, "type": "response", "entry_id": 4506592, "value": "USA" },
    { "id": 7894008, "type": "response", "entry_id": 4506593, "value": "222-333-4444" }
  ]
}

HTTP Request

GET https://www.gocanvas.com/api/v3/dispatches/194780

Response Parameters

Parameter Type Description
id integer The identifier for this exact Dispatch
type string The type of object returned
form_id integer The identifier for the Form associated with this Dispatch
user_id integer (optional) The identifier for the User assigned this Dispatch; Dispatch is considered unassigned if null
department_id integer The identifier for the Department associated with this Dispatch
submission_id integer (optional) The identifier for the Submission associated with this completed Dispatch
name string (optional) A short name for the Dispatch displayed on the Dispatch Calendar and the assigned user's calendar invitation
description string (optional) A short description of the Dispatch displayed on the assigned user's mobile device
status enum The state of the Dispatch
Can be unassigned, assigned, received, completed, or deleted
scheduled_at datetime (optional) For Scheduled Dispatches, the scheduled beginning time
scheduled_end datetime (optional) For Scheduled Dispatches, the scheduled ending time
sent_at datetime (optional) The time the Dispatch was sent
completed_at datetime (optional) The time the Dispatch was completed
deleted_at datetime (optional) The time the Dispatch was soft-deleted
send_calendar_invite boolean (optional) Whether a calendar invite is sent for the Dispatch
reminder_interval integer (optional) The period in minutes before the Dispatch event that a reminder will be sent
created_at datetime (optional) The time the Dispatch was created
responses[] array A collection of responses against Form Entries used to pre-populate the assignee's Submission
responses[].id integer The unique identifier for this Dispatch's response
responses[].type string The type of the object returned
responses[].entry_id integer The unique identifier of an Entry
responses[].value string The response data for the Entry
responses[].multi_key† string (optional) Reference to the looped value

† Only provided for looped forms

Create an Immediate Dispatch

Creating an Immediate Dispatch is similar to creating a Submission. The Dispatch will be sent to the mobile client immediately.

BODY='{
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "send_notification": true,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/dispatches
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "send_notification": true,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ]
}

uri = URI("https://www.gocanvas.com/api/v3/dispatches")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

dispatch_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "send_notification": true,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ]
};

fetch("https://www.gocanvas.com/api/v3/dispatches", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(dispatch => console.log(dispatch));

RESPONSE

{
  "id": 194780,
  "type": "dispatch_item",
  "form_id": 346103,
  "user_id": 840365,
  "department_id": 11942,
  "customer_id": null,
  "project_id": null,
  "site_id": null,
  "submission_id": null,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "status": "assigned",
  "scheduled_at": null,
  "scheduled_end": null,
  "sent_at": null,
  "completed_at": null,
  "deleted_at": null,
  "send_calendar_invite": false,
  "reminder_interval": null,
  "created_at": "2024-11-11 21:09:02 UTC"
}

HTTP Request

POST https://www.gocanvas.com/api/v3/dispatches

Request Body Parameters

Parameter Type Description
body hash The JSON Dispatch body
assignee_id integer (optional) The identifier for the User assigned the Dispatch; when this is not provided, the Dispatch remains unassigned
name string (optional) A short name for the Dispatch displayed on the Dispatch Calendar and the assigned user's calendar invitation
description string (optional) A short description of the Dispatch displayed on the assigned user's mobile device
dispatch_type enum The type of the Dispatch. Can be immediate_dispatch or scheduled_dispatch
department_id* integer (optional) The identifier for the Department the Dispatch will be created in
form_id integer The identifier to specify a Form
responses[] array A collection of responses against Form Entries used to pre-populate the assignee's Submission
responses[].entry_id integer The unique identifier of an Entry
responses[].entry_guid string The unique guid of an Entry. An alternative to entry_id
responses[].value string The response data for the Entry
responses[].multi_key† string (optional) Reference to the looped value
send_notification boolean (optional) Sends a push notification to the mobile app for the Dispatch when true
no_form_assignment boolean (optional) Allows creation of a Dispatch without the user being assigned to the form when true

* If no department_id is provided, the User's default department will be used. If the assignee is unassigned or has no default, the Form's originating department is used.

† Only required for looped forms

Create a Scheduled Dispatch

Dispatch scheduling allows for the Dispatch to be sent to the mobile client at a future date and time.

BODY='{
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "scheduled_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "reminder_interval": 60,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ],
  "scheduled_at": "12/1/2024 8:00:00 AM",
  "scheduled_end": "12/1/2024 12:00:00 PM"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/dispatches
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "scheduled_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "reminder_interval": 60,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ],
  "scheduled_at": "12/1/2024 8:00:00 AM",
  "scheduled_end": "12/1/2024 12:00:00 PM"
}

uri = URI("https://www.gocanvas.com/api/v3/dispatches")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

dispatch_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "scheduled_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "reminder_interval": 60,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ],
  "scheduled_at": "12/1/2024 8:00:00 AM",
  "scheduled_end": "12/1/2024 12:00:00 PM"
};

fetch("https://www.gocanvas.com/api/v3/dispatches", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(dispatch => console.log(dispatch));

RESPONSE

{
  "id": 194780,
  "type": "dispatch_item",
  "form_id": 346103,
  "user_id": 840365,
  "department_id": 11942,
  "customer_id": null,
  "project_id": null,
  "site_id": null,
  "submission_id": null,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "status": "assigned",
  "scheduled_at": "2024-12-01 08:00:00 UTC",
  "scheduled_end": "2024-12-01 12:00:00 UTC",
  "sent_at": null,
  "completed_at": null,
  "deleted_at": null,
  "send_calendar_invite": true,
  "reminder_interval": 60,
  "created_at": "2024-11-11 21:09:02 UTC"
}

HTTP Request

POST https://www.gocanvas.com/api/v3/dispatches

Request Body Parameters

Parameter Type Description
body hash The JSON Dispatch body
assignee_id integer (optional) The identifier for the User assigned the Dispatch; when this is not provided, the Dispatch remains unassigned
name string (optional) A short name for the Dispatch displayed on the Dispatch Calendar and the assigned user's calendar invitation
description string (optional) A short description of the Dispatch displayed on the assigned user's mobile device
dispatch_type enum The type of the Dispatch. Can be immediate_dispatch or scheduled_dispatch
department_id** integer (optional) The identifier for the Department the Dispatch will be created in
form_id integer The identifier to specify a Form
reminder_interval* integer (optional) The number of minutes before a Dispatch event that a reminder is sent
responses[] array A collection of responses against Form Entries used to pre-populate the assignee's Submission
responses[].entry_id integer The unique identifier of an Entry
responses[].value string The response data for the Entry
responses[].multi_key† string (optional) Reference to the looped value
scheduled_at* datetime The date and time the Dispatch is scheduled to begin. Uses formats "MM/DD/YYYY HH:mm/ss AM"
scheduled_end* datetime The date and time the Dispatch is scheduled to end. Uses formats "MM/DD/YYYY HH:mm/ss AM"
send_calendar_invite boolean (optional) Sends a calendar invite for the Dispatch when true
no_form_assignment boolean (optional) Allows creation of a Dispatch without the user being assigned to the form when true

* Only required for scheduled_dispatch type

** If no department_id is provided, the User's default department will be used. If the assignee is unassigned or has no default, the Form's originating department is used.

† Only required for looped forms

Create a Recurring Dispatch

Creating a Recurring Dispatch allows for the Dispatch to be sent to the mobile client on a recurring schedule.

BODY='{
  "assignee_id": 840365,
  "name": "Yearly Maintenance",
  "description": "Yearly Maintenance Service Request",
  "dispatch_type": "recurring_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "reminder_interval": 60,
  "repeat_interval": "daily",
  "repeat_ends_option": "ends_after",
  "repeat_ends_on": "12/1/2024",
  "repeat_occurrences": 2,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ],
  "scheduled_at": "12/1/2024 8:00:00 AM",
  "scheduled_end": "12/1/2024 12:00:00 PM"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/dispatches
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "assignee_id": 840365,
  "name": "Yearly Maintenance",
  "description": "Yearly Maintenance Service Request",
  "dispatch_type": "recurring_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "reminder_interval": 60,
  "repeat_interval": "daily",
  "repeat_ends_option": "ends_after",
  "repeat_ends_on": "12/1/2024",
  "repeat_occurrences": 2,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ],
  "scheduled_at": "12/1/2024 8:00:00 AM",
  "scheduled_end": "12/1/2024 12:00:00 PM"
}

uri = URI("https://www.gocanvas.com/api/v3/dispatches")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

dispatch_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "assignee_id": 840365,
  "name": "Yearly Maintenance",
  "description": "Yearly Maintenance Service Request",
  "dispatch_type": "recurring_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "reminder_interval": 60,
  "repeat_interval": "daily",
  "repeat_ends_option": "ends_after",
  "repeat_ends_on": "12/1/2024",
  "repeat_occurrences": 2,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ],
  "scheduled_at": "12/1/2024 8:00:00 AM",
  "scheduled_end": "12/1/2024 12:00:00 PM"
};

fetch("https://www.gocanvas.com/api/v3/dispatches", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(dispatch => console.log(dispatch));

RESPONSE

{
  "id": 194781,
  "type": "dispatch_item",
  "form_id": 346103,
  "user_id": 840365,
  "department_id": 11942,
  "customer_id": null,
  "project_id": null,
  "site_id": null,
  "submission_id": null,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "status": "assigned",
  "scheduled_at": "2024-12-01 08:00:00 UTC",
  "scheduled_end": "2024-12-01 12:00:00 UTC",
  "sent_at": null,
  "completed_at": null,
  "deleted_at": null,
  "send_calendar_invite": true,
  "reminder_interval": 60,
  "created_at": "2024-11-11 21:09:02 UTC", 
  "repeat_dispatch_schedule_id": 37842
}

HTTP Request

POST https://www.gocanvas.com/api/v3/dispatches

Request Body Parameters

Parameter Type Description
body hash The JSON Dispatch body
assignee_id integer (optional) The identifier for the User assigned the Dispatch; when this is not provided, the Dispatch remains unassigned
name string (optional) A short name for the Dispatch displayed on the Dispatch Calendar and the assigned user's calendar invitation
description string (optional) A short description of the Dispatch displayed on the assigned user's mobile device
dispatch_type enum The type of the Dispatch. Can be immediate_dispatch or scheduled_dispatch or recurring_dispatch
department_id** integer (optional) The identifier for the Department the Dispatch will be created in
form_id integer The identifier to specify a Form
reminder_interval integer (optional) The number of minutes before a Dispatch event that a reminder is sent
repeat_ends_option* enum The option for when the recurring dispatch ends. Valid values are ends_after, ends_on.
repeat_ends_on* string The date when the recurring dispatch ends. Required if repeat_ends_option is ends_on. Format: MM/DD/YYYY.
repeat_interval* enum The interval for the recurring dispatch. Valid values are daily, weekdays, weekly, monthly_day, monthly_date, yearly.***
repeat_occurrences integer (optional) The number of occurrences for the recurring dispatch. Required if repeat_ends_option is ends_after.
responses[] array A collection of responses against Form Entries used to pre-populate the assignee's Submission
responses[].entry_id integer The unique identifier of an Entry
responses[].value string The response data for the Entry
responses[].multi_key† string (optional) Reference to the looped value
scheduled_at* datetime The date and time the Dispatch is scheduled to begin. Uses formats "MM/DD/YYYY HH:mm/ss AM"
scheduled_end* datetime The date and time the Dispatch is scheduled to end. Uses formats "MM/DD/YYYY HH:mm/ss AM"
send_calendar_invite boolean (optional) Sends a calendar invite for the Dispatch when true
no_form_assignment boolean (optional) Allows creation of a Dispatch without the user being assigned to the form when true

* Only Required for recurring_dispatch type

** If no department_id is provided, the User's default department will be used. If the assignee is unassigned or has no default, the Form's originating department is used.

*** monthly_date refers to the day of the month (e.g. "Monthly on the 18th"). monthly_day refers to the week of the month and the day of the week (e.g. "Monthly on the 3rd Thursday").

† Only required for looped forms

Create a Dispatch with loops

Loop screens can be configured when designing a form, for information on how to configure loop screens, please refer to Loop Screens. Responses in loop screens use the multi_key field to identify the looped value.

BODY='{
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" },
    { "entry_id": 4506600, "value": "Unit 201" },
    { "entry_id": 4506594, "multi_key": "Unit 201", "value": "High" },
    { "entry_id": 4506595, "multi_key": "Unit 201", "value": "Water Leak" }
  ]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/dispatches
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" },
    { "entry_id": 4506600, "value": "Unit 201" },
    { "entry_id": 4506594, "multi_key": "Unit 201", "value": "High" },
    { "entry_id": 4506595, "multi_key": "Unit 201", "value": "Water Leak" }
  ]
}

uri = URI("https://www.gocanvas.com/api/v3/dispatches")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

dispatch_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" },
    { "entry_id": 4506600, "value": "Unit 201" },
    { "entry_id": 4506594, "multi_key": "Unit 201", "value": "High" },
    { "entry_id": 4506595, "multi_key": "Unit 201", "value": "Water Leak" }
  ]
};

fetch("https://www.gocanvas.com/api/v3/dispatches", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(dispatch => console.log(dispatch));

RESPONSE

{
  "id": 194780,
  "type": "dispatch_item",
  "form_id": 346103,
  "user_id": 840365,
  "department_id": 11942,
  "customer_id": null,
  "project_id": null,
  "site_id": null,
  "submission_id": null,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "status": "assigned",
  "scheduled_at": null,
  "scheduled_end": null,
  "sent_at": null,
  "completed_at": null,
  "deleted_at": null,
  "send_calendar_invite": false,
  "reminder_interval": null,
  "created_at": "2024-11-11 21:09:02 UTC"
}

HTTP Request

POST https://www.gocanvas.com/api/v3/dispatches

Request Body Parameters

Parameter Type Description
body hash The JSON Dispatch body
assignee_id integer (optional) The identifier for the User assigned the Dispatch; when this is not provided, the Dispatch remains unassigned
name string (optional) A short name for the Dispatch displayed on the Dispatch Calendar and the assigned user's calendar invitation
description string (optional) A short description of the Dispatch displayed on the assigned user's mobile device
dispatch_type enum The type of the Dispatch. Can be immediate_dispatch or scheduled_dispatch
department_id* integer (optional) The identifier for the Department the Dispatch will be created in
form_id integer The identifier to specify a Form
responses[] array A collection of responses against Form Entries used to pre-populate the assignee's Submission
responses[].entry_id integer The unique identifier of an Entry
responses[].entry_guid string The unique guid of an Entry. An alternative to entry_id
responses[].value string The response data for the Entry
responses[].multi_key† string (optional) Reference to the looped value
send_notification boolean (optional) Sends a push notification to the mobile app for the Dispatch when true
no_form_assignment boolean (optional) Allows creation of a Dispatch without the user being assigned to the form when true

* If no department_id is provided, the User's default department will be used. If the assignee is unassigned or has no default, the Form's originating department is used.

† Only required for looped forms

Customers, Projects, and Sites

Dispatches may be created and associated with Customers, Projects, or Sites. This allows for Dispatches to be organized and tracked within the Project Management Views.

Dispatches associated with Customers, Projects, or Sites support the same parameters as Dispatches without associations such as loops and scheduling. Additional parameters such as customer_id are used to create the association.

BODY='{
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "project_id": 11,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/dispatches
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "project_id": 11,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ]
}

uri = URI("https://www.gocanvas.com/api/v3/dispatches")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

dispatch_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "assignee_id": 840365,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "dispatch_type": "immediate_dispatch",
  "department_id": 11942,
  "form_id": 346103,
  "project_id": 11,
  "responses": [
    { "entry_id": 4506586, "value": "Jane" },
    { "entry_id": 4506587, "value": "Doe" },
    { "entry_id": 4506588, "value": "Main Street" },
    { "entry_id": 4506589, "value": "Boca Raton" },
    { "entry_id": 4506590, "value": "FL" },
    { "entry_id": 4506591, "value": "23456" },
    { "entry_id": 4506592, "value": "USA" },
    { "entry_id": 4506593, "value": "222-333-4444" }
  ]
};

fetch("https://www.gocanvas.com/api/v3/dispatches", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(dispatch => console.log(dispatch));

RESPONSE

{
  "id": 194780,
  "type": "dispatch_item",
  "form_id": 346103,
  "user_id": 840365,
  "department_id": 11942,
  "customer_id": null,
  "project_id": 11,
  "site_id": null,
  "submission_id": null,
  "name": "Repair request",
  "description": "123 Main St Service Request",
  "status": "assigned",
  "scheduled_at": null,
  "scheduled_end": null,
  "sent_at": null,
  "completed_at": null,
  "deleted_at": null,
  "send_calendar_invite": false,
  "reminder_interval": null,
  "created_at": "2024-11-11 21:09:02 UTC"
}

HTTP Request

POST https://www.gocanvas.com/api/v3/dispatches

Request Body Parameters

Parameter Type Description
body hash The JSON Dispatch body
assignee_id integer (optional) The identifier for the User assigned the Dispatch; when this is not provided, the Dispatch remains unassigned
name string (optional) A short name for the Dispatch displayed on the Dispatch Calendar and the assigned user's calendar invitation
description string (optional) A short description of the Dispatch displayed on the assigned user's mobile device
dispatch_type enum The type of the Dispatch. Can be immediate_dispatch or scheduled_dispatch
form_id integer The identifier to specify a Form
customer_id integer (optional) The identifier of the Customer to associate the Dispatch with
project_id integer (optional) The identifier of the Project to associate the Dispatch with
site_id integer (optional) The identifier of the Site to associate the Dispatch with
responses[] array A collection of responses against Form Entries used to pre-populate the assignee's Submission
responses[].entry_id integer The unique identifier of an Entry
responses[].value string The response data for the Entry
responses[].multi_key† string Reference to the looped value

† Only required for looped forms

Delete a Dispatch

A Dispatch can be deleted with a DELETE request.

By default, the DELETE request will only soft delete the Dispatch which preserves the Dispatch data and removes it from mobile device task lists. To permanently delete the Dispatch, include the hard_delete parameter with a value of true, e.g. DELETE https://www.gocanvas.com/api/v3/dispatches/194781?hard_delete=true .

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/dispatches/194781
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/dispatches/194781")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

dispatch_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/dispatches/194781", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(dispatch => console.log(dispatch));

RESPONSE

{
  "message": "Dispatch 194781 has been soft deleted successfully"
}

HTTP Request

DELETE https://www.gocanvas.com/api/v3/dispatches/194781

Request Parameters

Parameter Type Description
hard_delete* boolean Will hard delete the Dispatch record when set to true

* This is an optional URL parameter. If not provided, the Dispatch will be soft deleted.

Form

A Form is how you capture data with GoCanvas. It defines all data you wish to collect.

The Form object

EXAMPLE

{
  "id": 346127,
  "type": "form",
  "name": "Basic Form",
  "description": "User Info",
  "status": "published",
  "version": 1,
  "root_version_id": 346127,
  "workflow_enabled": false,
  "dispatch_enabled": false,
  "web_form": false,
  "email_options": 2,
  "view_pdf_mobile": true,
  "is_locked_by_canvas": false,
  "mobile_builder_enabled": false,
  "sheet_style_enabled": true,
  "builderVersion": "3",
  "sections": [
    {
      "id": 8969,
      "type": "section",
      "form_id": 346127,
      "description": "User Info",
      "position": 0,
      "section_type_id": 10,
      "hides_detailed_description": false,
      "sheets": [
        {
          "id": 10278,
          "type": "sheet",
          "form_id": 346127,
          "section_id": 8969,
          "description": "User Info",
          "position": 0,
          "sheet_type_id": 11,
          "inserts_page_break_at_the_end": false,
          "show_sheet_name": true,
          "allow_duplicate": null,
          "style": 0,
          "integration_form": false,
          "entries": [
            {
              "id": 51464,
              "type": "entry",
              "form_id": 346127,
              "sheet_id": 10278,
              "entry_type_id": 10,
              "label": "NAME",
              "default": null,
              "length": null,
              "required": false,
              "position": 0,
              "guid": "2F04C1F7C3CE7A29F3E7351619181168339182D0",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51465,
              "type": "entry",
              "form_id": 346127,
              "sheet_id": 10278,
              "entry_type_id": 10,
              "label": "ADDRESS",
              "default": null,
              "length": null,
              "required": false,
              "position": 1,
              "guid": "93C144AD3E0BD7612C7075B43562E752F4247CDF",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51466,
              "type": "entry",
              "form_id": 346127,
              "sheet_id": 10278,
              "entry_type_id": 10,
              "label": "CITY",
              "default": null,
              "length": null,
              "required": false,
              "position": 2,
              "guid": "21C29FA4B978ACEC738392B99479C41B3AA645C2",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51467,
              "type": "entry",
              "form_id": 346127,
              "sheet_id": 10278,
              "entry_type_id": 15,
              "label": "STATE",
              "default": "",
              "length": null,
              "required": false,
              "position": 3,
              "guid": "D8A8A397FFAD78F50EB96128B169815A5852F5BF",
              "original_type_id": 5,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": 2.0,
              "maximum": 5.0,
              "mask": null,
              "style": 1,
              "barcode_enabled": false,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [
                {
                  "id": 786229650,
                  "type": "entry_value",
                  "entry_id": 51467,
                  "text": "ARIZONA",
                  "position": 0
                },
                {
                  "id": 786229651,
                  "type": "entry_value",
                  "entry_id": 51467,
                  "text": "ALASKA",
                  "position": 1
                },
                {
                  "id": 786229652,
                  "type": "entry_value",
                  "entry_id": 51467,
                  "text": "ALABAMA",
                  "position": 2
                },
                {
                  "id": 786229653,
                  "type": "entry_value",
                  "entry_id": 51467,
                  "text": null,
                  "position": 3
                }
              ],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            }
          ],
          "conditions": [],
          "multi_section": null,
          "display_entry": null
        }
      ]
    }
  ]
}
{
  "id": 4639578,
  "type": "form",
  "name": "Loop Screen Form",
  "description": null,
  "status": "published",
  "version": 1,
  "root_version_id": 4639578,
  "workflow_enabled": false,
  "dispatch_enabled": false,
  "web_form": false,
  "email_options": 2,
  "view_pdf_mobile": true,
  "is_locked_by_canvas": false,
  "mobile_builder_enabled": false,
  "sheet_style_enabled": true,
  "builderVersion": "3",
  "sections": [
    {
      "id": 8976,
      "type": "section",
      "form_id": 4639578,
      "description": "Customer Information",
      "position": 0,
      "section_type_id": 10,
      "hides_detailed_description": false,
      "sheets": [
        {
          "id": 10285,
          "type": "sheet",
          "form_id": 4639578,
          "section_id": 8976,
          "description": "Customer Information",
          "position": 0,
          "sheet_type_id": 11,
          "inserts_page_break_at_the_end": false,
          "show_sheet_name": true,
          "allow_duplicate": null,
          "style": 0,
          "integration_form": false,
          "entries": [
            {
              "id": 51484,
              "type": "entry",
              "form_id": 4639578,
              "sheet_id": 10285,
              "entry_type_id": 10,
              "label": "Phone",
              "default": null,
              "length": null,
              "required": false,
              "position": 0,
              "guid": "50A2A42F8E73D8740196E7144F345A1259DABBAD",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51485,
              "type": "entry",
              "form_id": 4639578,
              "sheet_id": 10285,
              "entry_type_id": 10,
              "label": "Email",
              "default": null,
              "length": null,
              "required": false,
              "position": 1,
              "guid": "4F305761009933A5AF3BC62273C1FCA26DB8DD91",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51486,
              "type": "entry",
              "form_id": 4639578,
              "sheet_id": 10285,
              "entry_type_id": 10,
              "label": "Name",
              "default": null,
              "length": null,
              "required": false,
              "position": 2,
              "guid": "940661D995630AB3FBBEC8F0B22A28F4B359436F",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            }
          ],
          "conditions": [],
          "multi_section": null,
          "display_entry": null
        }
      ]
    },
    {
      "id": 8977,
      "type": "section",
      "form_id": 4639578,
      "description": "Service Request",
      "position": 1,
      "section_type_id": 10,
      "hides_detailed_description": false,
      "sheets": [
        {
          "id": 10287,
          "type": "sheet",
          "form_id": 4639578,
          "section_id": 8977,
          "description": "Service Request",
          "position": 0,
          "sheet_type_id": 15,
          "inserts_page_break_at_the_end": false,
          "show_sheet_name": true,
          "allow_duplicate": null,
          "style": 0,
          "integration_form": false,
          "entries": [
            {
              "id": 51489,
              "type": "entry",
              "form_id": 4639578,
              "sheet_id": 10287,
              "entry_type_id": 10,
              "label": "Address",
              "default": null,
              "length": null,
              "required": false,
              "position": 0,
              "guid": "37AC77CE6AE7FF08F4BAF9BBDA06CCFB6F9820A9",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            }
          ],
          "conditions": [],
          "multi_section": {
            "id": 8978,
            "type": "section",
            "form_id": 4639578,
            "description": "Service Requested",
            "position": 2,
            "section_type_id": 11,
            "hides_detailed_description": true
          },
          "display_entry": null
        }
      ]
    },
    {
      "id": 8978,
      "type": "section",
      "form_id": 4639578,
      "description": "Service Requested",
      "position": 2,
      "section_type_id": 11,
      "hides_detailed_description": true,
      "sheets": [
        {
          "id": 10286,
          "type": "sheet",
          "form_id": 4639578,
          "section_id": 8978,
          "description": "Service Requested",
          "position": 0,
          "sheet_type_id": 11,
          "inserts_page_break_at_the_end": false,
          "show_sheet_name": true,
          "allow_duplicate": null,
          "style": 0,
          "integration_form": false,
          "entries": [
            {
              "id": 51487,
              "type": "entry",
              "form_id": 4639578,
              "sheet_id": 10286,
              "entry_type_id": 15,
              "label": "Priority",
              "default": "GC_BLANK_DEFAULT",
              "length": null,
              "required": false,
              "position": 0,
              "guid": "1162B07CF6BD1C8406C5B1D418793AB93994CF8C",
              "original_type_id": 5,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": 2.0,
              "maximum": 5.0,
              "mask": null,
              "style": 1,
              "barcode_enabled": false,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [
                {
                  "id": 786229668,
                  "type": "entry_value",
                  "entry_id": 51487,
                  "text": "High",
                  "position": 0
                },
                {
                  "id": 786229669,
                  "type": "entry_value",
                  "entry_id": 51487,
                  "text": "Medium",
                  "position": 1
                },
                {
                  "id": 786229670,
                  "type": "entry_value",
                  "entry_id": 51487,
                  "text": "Low",
                  "position": 2
                }
              ],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51488,
              "type": "entry",
              "form_id": 4639578,
              "sheet_id": 10286,
              "entry_type_id": 15,
              "label": "Service Requested",
              "default": "GC_BLANK_DEFAULT",
              "length": null,
              "required": false,
              "position": 1,
              "guid": "AC5B9BF04298B2B0E099680DDDBE17CB04627692",
              "original_type_id": 5,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": 2.0,
              "maximum": 5.0,
              "mask": null,
              "style": 1,
              "barcode_enabled": false,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [
                {
                  "id": 786229671,
                  "type": "entry_value",
                  "entry_id": 51488,
                  "text": "Painting",
                  "position": 0
                },
                {
                  "id": 786229672,
                  "type": "entry_value",
                  "entry_id": 51488,
                  "text": "Cleaning",
                  "position": 1
                },
                {
                  "id": 786229673,
                  "type": "entry_value",
                  "entry_id": 51488,
                  "text": "Replacement",
                  "position": 2
                },
                {
                  "id": 786229674,
                  "type": "entry_value",
                  "entry_id": 51488,
                  "text": "Repair / Maintenance",
                  "position": 3
                }
              ],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            }
          ],
          "conditions": [],
          "multi_section": null,
          "display_entry": null
        }
      ]
    }
  ]
}

Forms are organized into Sections and Sheets, which hold individual Entries. Entries are questions that the user will answer.

List all Forms

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

forms_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(forms => console.log(forms));

Users can view a list of all the Forms to which they have access.

RESPONSE

[
  {
    "id": 346127,
    "type": "form",
    "name": "Basic Form",
    "description": "User Info",
    "status": "published",
    "version": 1,
    "root_version_id": 346127,
    "dispatch_enabled": true,
    "workflow_enabled": false,
    "web_form": true,
    "email_options": 2,
    "view_pdf_mobile": true
  },
  {
    "id": 4639578,
    "type": "form",
    "name": "Loop Screen Form",
    "description": null,
    "status": "published",
    "version": 1,
    "root_version_id": 4639578,
    "dispatch_enabled": false,
    "workflow_enabled": false,
    "web_form": false,
    "email_options": 2,
    "view_pdf_mobile": true
  }
]

HTTP Request

GET https://www.gocanvas.com/api/v3/forms

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1

Retrieve a Form

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms/346127
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/346127")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

form_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/346127", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(form => console.log(form));

Users can view basic or looped screen Form.

HTTP Request (Regular Form)

GET https://www.gocanvas.com/api/v3/forms/346127?format=flat

Query Parameters

Most use cases rely on the flat format. This will return a single JSON object with all the information needed to render a Form in a client application. If no format is specified, the default is nested.

Parameter Description Options
format Specifies the format of the form definition nested, flat, minimal, metadata

Retrieve a Form (nested)

nested: Provides a full understanding of the form definition, presented in a nested format.

Back to Retrieve a Form

RESPONSE

{
  "id": 346127,
  "type": "form",
  "name": "Basic Form",
  "description": null,
  "status": "published",
  "version": 1,
  "root_version_id": 346127,
  "workflow_enabled": false,
  "dispatch_enabled": false,
  "web_form": false,
  "email_options": 2,
  "view_pdf_mobile": true,
  "is_locked_by_canvas": false,
  "mobile_builder_enabled": false,
  "sheet_style_enabled": true,
  "builderVersion": "3",
  "sections": [
    {
      "id": 8980,
      "type": "section",
      "form_id": 346127,
      "description": "User Info",
      "position": 0,
      "section_type_id": 10,
      "hides_detailed_description": false,
      "sheets": [
        {
          "id": 10289,
          "type": "sheet",
          "form_id": 346127,
          "section_id": 8980,
          "description": "User Info",
          "position": 0,
          "sheet_type_id": 11,
          "inserts_page_break_at_the_end": false,
          "show_sheet_name": true,
          "allow_duplicate": null,
          "style": 0,
          "integration_form": false,
          "entries": [
            {
              "id": 51498,
              "type": "entry",
              "form_id": 346127,
              "sheet_id": 10289,
              "entry_type_id": 10,
              "label": "NAME",
              "default": null,
              "length": null,
              "required": false,
              "position": 0,
              "guid": "2F04C1F7C3CE7A29F3E7351619181168339182D0",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51499,
              "type": "entry",
              "form_id": 346127,
              "sheet_id": 10289,
              "entry_type_id": 10,
              "label": "ADDRESS",
              "default": null,
              "length": null,
              "required": false,
              "position": 1,
              "guid": "93C144AD3E0BD7612C7075B43562E752F4247CDF",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51500,
              "type": "entry",
              "form_id": 346127,
              "sheet_id": 10289,
              "entry_type_id": 10,
              "label": "CITY",
              "default": null,
              "length": null,
              "required": false,
              "position": 2,
              "guid": "21C29FA4B978ACEC738392B99479C41B3AA645C2",
              "original_type_id": 0,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": null,
              "maximum": null,
              "mask": null,
              "style": 0,
              "barcode_enabled": null,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            },
            {
              "id": 51501,
              "type": "entry",
              "form_id": 346127,
              "sheet_id": 10289,
              "entry_type_id": 15,
              "label": "STATE",
              "default": "",
              "length": null,
              "required": false,
              "position": 3,
              "guid": "D8A8A397FFAD78F50EB96128B169815A5852F5BF",
              "original_type_id": 5,
              "reference_data_column": null,
              "reference_data_id": null,
              "live_data_source_id": null,
              "live_data_source_column": null,
              "data_source_context_id": null,
              "read_only": false,
              "visible": true,
              "pdf_visibility": 0,
              "web_visibility": 0,
              "receipt_label": null,
              "report_label": null,
              "export_label": null,
              "auto_email_subject": false,
              "auto_email_body": false,
              "auto_email_filename": false,
              "inserts_page_break_at_the_end": false,
              "auto_submission_name": false,
              "minimum": 2.0,
              "maximum": 5.0,
              "mask": null,
              "style": 1,
              "barcode_enabled": false,
              "integration_form": false,
              "gps_display_type": null,
              "zoom_level": null,
              "gps_accuracy": null,
              "gps_timeout": null,
              "gps_accuracy_required": false,
              "summary_entry": null,
              "reference_image_id": null,
              "entry_values": [
                {
                  "id": 786229679,
                  "type": "entry_value",
                  "entry_id": 51501,
                  "text": "ARIZONA",
                  "position": 0
                },
                {
                  "id": 786229680,
                  "type": "entry_value",
                  "entry_id": 51501,
                  "text": "ALASKA",
                  "position": 1
                },
                {
                  "id": 786229681,
                  "type": "entry_value",
                  "entry_id": 51501,
                  "text": "ALABAMA",
                  "position": 2
                },
                {
                  "id": 786229682,
                  "type": "entry_value",
                  "entry_id": 51501,
                  "text": null,
                  "position": 3
                }
              ],
              "operations": [],
              "dependent_entry": null,
              "conditions": []
            }
          ],
          "conditions": [],
          "multi_section": null,
          "display_entry": null
        }
      ]
    }
  ]
}

Response Parameters (nested format)

Form responses are organized in a nested format, with the Form at the top level, Sections nested within the Form, Sheets nested within Sections, and Entries nested within Sheets. Each level has its own parameters, detailed in the tables below.

Form Level

Parameter Type Description
id integer The identifier for this exact version of the Form
name string The name of the Form
status * enum The status of the Form.
Can be new, pending, published, or archived
description string The description of the Form
version integer The version number of the Form. When a new version is saved and published, this version counter increments
root_version_id integer The original Form identifier for all versions of the Form
workflow_enabled boolean Whether the Form has Workflow enabled
dispatch_enabled boolean Whether the Form has Dispatch enabled
web_form boolean Whether the Form is a web form
email_options integer The email option for mobile submitters of the Form.
0: Cannot email PDF
1: Can email PDF to themselves only
2: Can email PDF to anyone
view_pdf_mobile boolean Whether mobile submitters of the Form can view the PDF of their submission on their device
is_locked_by_canvas boolean Whether the Form is currently locked by the application.
Forms may be temporarily locked when being used in integrations.
mobile_builder_enabled boolean Whether the Form has Mobile Builder (deprecated) enabled
sheet_style_enabled boolean Whether the Form has the grid sheet style enabled
builder_version integer The default version of the Form Builder that will be opened when editing the Form, 3 is current Advanced Builder
sections[] array A list of Sections within the Form

* Only one version of a Form will be in published status at a time. This is the version of the Form accepting new Submissions.

Section Level

Sections are nested within the Form. The full path for these parameters is sections[].{parameter}.

Parameter Type Description
id integer The identifier to specify a Section
form_id integer The identifier of the Form that the Section belongs to
description string The description of a Section
position integer The ordinal position of the Section, 0-indexed
section_type_id integer The identifier of the Section Type for the Section
10: Normal Section
11: Multiple Entry Section
sheets[] array A list of Sheets within the Section

Sheet Level

Sheets are nested within Sections. The full path for these parameters is sections[].sheets[].{parameter}.

Parameter Type Description
id integer The identifier to specify a Sheet
form_id integer The identifier of the Form that the Sheet belongs to
section_id integer The identifier of the Section that the Sheet belongs to
description string The description of a Sheet
position integer The ordinal position of the Sheet, 0-indexed
sheet_type_id integer The identifier of the Sheet Type for the Sheet
10: Labels Left
11: Labels Above
12: Single Entry
13: List (Advanced)
14: Signature
15: List (Simple)
16: Drawing Pad
inserts_page_break_at_the_end boolean Whether basic PDF adds a page break after this Sheet
show_sheet_name boolean Whether basic PDF displays the Sheet name
allow_duplicate boolean Whether duplicate key fields are allowed in loops by clients
style integer The presentation style of the Sheet when looped
0: Labels Above
1: Table
2: Table (pre-populated)
integration_form boolean (Deprecated) Whether this Sheet came from a Form which came from a public template, usually false for all Forms
multi_section integer The identifier of the multi-section associated with this Sheet (for loop screens)
display_entry integer The identifier of the Entry used as the display field (for loop screens)
entries[] array A list of Entries (fields/questions) within the Sheet
conditions[] array A list of conditional logic rules for this Sheet

Entry Level

Entries are nested within Sheets. The full path for these parameters is sections[].sheets[].entries[].{parameter}.

Parameter Type Description
id integer The identifier of the Entry
form_id integer The identifier of the Form that the Entry belongs to
sheet_id integer The identifier of the Sheet that the Entry belongs to
entry_type_id integer (Deprecated) The identifier of the Entry Type for the Entry, original_type_id is preferred
label string The prompt or question for an Entry
default string The default value for the Entry
length integer The maximum character length for Entries
required boolean Whether the Entry is required to be filled out
position integer The ordinal position of the Entry within the Sheet, 0-indexed
guid string A globally unique identifier for the Entry.
This persists across versions of the Form if the Entry exists in multiple versions
original_type_id integer The type identifier for the Entry Type
0: Text Box
1: Integer
2: Decimal
3: Date
4: Time
5: Value List
6: Attachment
7: Checkbox
8: Multi-Line Text
9: Static Text
10: Image Capture
12: Web Link
13: Payment
20: Summary
21: Calculation
22: GPS
23: Mirror
24: Static Image
25: Multi Photo
98: Drawing
99: Signature
100: Video
200: Dependent Form
reference_data_column string The column name from Reference Data linked to this Entry
reference_data_id integer The identifier of the Reference Data source linked to this Entry
live_data_source_id integer The identifier of the Live Data source linked to this Entry
live_data_source_column string The column name from Live Data source linked to this Entry
data_source_context_id integer The identifier for data source context configuration
read_only boolean Whether the Entry is read-only
visible boolean Whether the Entry is visible to client users
pdf_visibility integer The PDF visibility option for this Entry
0: Always
1: Never
2: Only if field is not empty
3: Only if default value has been changed
4: Only if default value has been changed & field is not empty
5: Only to addresses set on email options page
web_visibility integer The web visibility option for this Entry
0: Always
1: Never
2: Only if field is not empty
3: Only if default value has been changed
4: Only if default value has been changed & field is not empty
receipt_label string Custom label for this Entry on receipts
report_label string Custom label for this Entry in reports
export_label string Custom label for this Entry in exports
auto_email_subject boolean Whether this Entry's value is automatically used in email subjects
auto_email_body boolean Whether this Entry's value is automatically used in email bodies
auto_email_filename boolean Whether this Entry's value is automatically used in email filenames
inserts_page_break_at_the_end boolean Whether a page break is inserted after this Entry in standard PDF
auto_submission_name boolean Whether this Entry's value is automatically used as the Submission name
minimum number The minimum value for the Entry
maximum number The maximum value for the Entry
mask string Input mask pattern for the Entry
style integer The presentation style for choice-based Entries
0: Default
1: Dropdown
barcode_enabled boolean Whether barcode scanning is enabled for this Entry
integration_form boolean (Deprecated) Whether this Entry came from a Form which came from a public template
gps_display_type integer The display format for GPS Entries
zoom_level integer The map zoom level for GPS Entries
gps_accuracy number The required GPS accuracy in meters
gps_timeout integer The GPS timeout in milliseconds
gps_accuracy_required boolean Whether GPS accuracy is enforced
summary_entry object Reference to the Entry being summarized (for Summary type Entries)
reference_image_id integer The identifier of the reference image for Static Image Entries
entry_values[] array List of choice options for Value List, Dropdown, and similar Entries
operations[] array List of operations (calculations/rules) applied to this Entry
dependent_entry object Reference to dependent form Entry configuration
conditions[] array List of conditional logic rules for this Entry

Entry Values Level

Entry Values are the list of Choices populating Dropdown type Entries. They are nested within Entries. The full path for these parameters is sections[].sheets[].entries[].entry_values[].{parameter}.

Parameter Type Description
id integer The identifier for this choice option
entry_id integer The identifier of the Entry this choice belongs to
text string The display text for this choice option
position integer The ordinal position of this choice, 0-indexed

Retrieve a Form (flat)

flat: Provides a full understanding of the form definition, presented in a flattened format.

Back to Retrieve a Form

RESPONSE

{
  "id": 346127,
  "type": "form",
  "name": "Basic Form",
  "description": null,
  "status": "published",
  "version": 1,
  "root_version_id": 346127,
  "workflow_enabled": false,
  "dispatch_enabled": false,
  "web_form": false,
  "email_options": 2,
  "view_pdf_mobile": true,
  "builderVersion": "3",
  "sections": [
    {
      "id": 8980,
      "type": "section",
      "form_id": 346127,
      "description": "User Info",
      "position": 0,
      "section_type_id": 10,
      "original_type_id": 0
    }
  ],
  "sheets": [
    {
      "id": 10289,
      "type": "sheet",
      "form_id": 346127,
      "section_id": 8980,
      "description": "User Info",
      "position": 0,
      "sheet_type_id": 11,
      "allow_duplicate": null,
      "style": 0,
      "original_type_id": 1,
      "conditions": [],
      "multi_section": null,
      "display_entry": null
    }
  ],
  "entries": [
    {
      "id": 51498,
      "type": "Text",
      "form_id": 346127,
      "sheet_id": 10289,
      "entry_type_id": 10,
      "label": "NAME",
      "default": null,
      "length": null,
      "required": false,
      "position": 0,
      "guid": "2F04C1F7C3CE7A29F3E7351619181168339182D0",
      "original_type_id": 0,
      "minimum": null,
      "maximum": null,
      "mask": null,
      "style": 0,
      "gps_timeout": null,
      "gps_accuracy": null,
      "gps_accuracy_required": false,
      "barcode_enabled": null,
      "reference_data_column": null,
      "reference_data_id": null,
      "live_data_source_id": null,
      "live_data_source_column": null,
      "data_source_context_id": null,
      "read_only": false,
      "visible": true,
      "receipt_label": null,
      "summary_entry": null,
      "reference_image_id": null,
      "entry_values": [],
      "dependent_entry": null,
      "export_label": null,
      "pdf_visibility": 0
    },
    {
      "id": 51499,
      "type": "Text",
      "form_id": 346127,
      "sheet_id": 10289,
      "entry_type_id": 10,
      "label": "ADDRESS",
      "default": null,
      "length": null,
      "required": false,
      "position": 1,
      "guid": "93C144AD3E0BD7612C7075B43562E752F4247CDF",
      "original_type_id": 0,
      "minimum": null,
      "maximum": null,
      "mask": null,
      "style": 0,
      "gps_timeout": null,
      "gps_accuracy": null,
      "gps_accuracy_required": false,
      "barcode_enabled": null,
      "reference_data_column": null,
      "reference_data_id": null,
      "live_data_source_id": null,
      "live_data_source_column": null,
      "data_source_context_id": null,
      "read_only": false,
      "visible": true,
      "receipt_label": null,
      "summary_entry": null,
      "reference_image_id": null,
      "entry_values": [],
      "dependent_entry": null,
      "export_label": null,
      "pdf_visibility": 0
    },
    {
      "id": 51500,
      "type": "Text",
      "form_id": 346127,
      "sheet_id": 10289,
      "entry_type_id": 10,
      "label": "CITY",
      "default": null,
      "length": null,
      "required": false,
      "position": 2,
      "guid": "21C29FA4B978ACEC738392B99479C41B3AA645C2",
      "original_type_id": 0,
      "minimum": null,
      "maximum": null,
      "mask": null,
      "style": 0,
      "gps_timeout": null,
      "gps_accuracy": null,
      "gps_accuracy_required": false,
      "barcode_enabled": null,
      "reference_data_column": null,
      "reference_data_id": null,
      "live_data_source_id": null,
      "live_data_source_column": null,
      "data_source_context_id": null,
      "read_only": false,
      "visible": true,
      "receipt_label": null,
      "summary_entry": null,
      "reference_image_id": null,
      "entry_values": [],
      "dependent_entry": null,
      "export_label": null,
      "pdf_visibility": 0
    },
    {
      "id": 51501,
      "type": "Single Choice",
      "form_id": 346127,
      "sheet_id": 10289,
      "entry_type_id": 15,
      "label": "STATE",
      "default": "",
      "length": null,
      "required": false,
      "position": 3,
      "guid": "D8A8A397FFAD78F50EB96128B169815A5852F5BF",
      "original_type_id": 5,
      "minimum": 2.0,
      "maximum": 5.0,
      "mask": null,
      "style": 1,
      "gps_timeout": null,
      "gps_accuracy": null,
      "gps_accuracy_required": false,
      "barcode_enabled": false,
      "reference_data_column": null,
      "reference_data_id": null,
      "live_data_source_id": null,
      "live_data_source_column": null,
      "data_source_context_id": null,
      "read_only": false,
      "visible": true,
      "receipt_label": null,
      "summary_entry": null,
      "reference_image_id": null,
      "entry_values": [
        {
          "id": 786229679,
          "type": "entry_value",
          "entry_id": 51501,
          "text": "ARIZONA",
          "position": 0
        },
        {
          "id": 786229680,
          "type": "entry_value",
          "entry_id": 51501,
          "text": "ALASKA",
          "position": 1
        },
        {
          "id": 786229681,
          "type": "entry_value",
          "entry_id": 51501,
          "text": "ALABAMA",
          "position": 2
        },
        {
          "id": 786229682,
          "type": "entry_value",
          "entry_id": 51501,
          "text": null,
          "position": 3
        }
      ],
      "dependent_entry": null,
      "export_label": null,
      "pdf_visibility": 0
    }
  ],
  "conditions": [],
  "operations": [],
  "data_source_contexts": [],
  "data_source_context_params": []
}

Retrieve a Form (minimal)

minimal: Provides a basic understanding of the form definition.

Back to Retrieve a Form

RESPONSE

{
    "id": 346127,
    "type": "form",
    "name": "Basic Form",
    "description": null,
    "status": "published",
    "version": 1,
    "root_version_id": 346127,
    "workflow_enabled": false,
    "dispatch_enabled": false,
    "web_form": false,
    "email_options": 2,
    "view_pdf_mobile": true,
    "entries": [
        {
            "id": 51498,
            "type": "entry",
            "sheet_id": 10289,
            "entry_type_id": 10,
            "label": "NAME",
            "entry_type": "text_field"
        },
        {
            "id": 51499,
            "type": "entry",
            "sheet_id": 10289,
            "entry_type_id": 10,
            "label": "ADDRESS",
            "entry_type": "text_field"
        },
        {
            "id": 51500,
            "type": "entry",
            "sheet_id": 10289,
            "entry_type_id": 10,
            "label": "CITY",
            "entry_type": "text_field"
        },
        {
            "id": 51501,
            "type": "entry",
            "sheet_id": 10289,
            "entry_type_id": 15,
            "label": "STATE",
            "entry_type": "drop_down"
        }
    ]
}

Retrieve a Form (metadata)

metadata: Provides information about the form, such as which version is published.

Back to Retrieve a Form

RESPONSE

{
  "id": 346127,
  "type": "form",
  "name": "Basic Form",
  "description": null,
  "status": "published",
  "version": 1,
  "root_version_id": 346127,
  "dispatch_enabled": true,
  "workflow_enabled": false,
  "web_form": true,
  "email_options": 2,
  "view_pdf_mobile": true
}

Create a Form

# First, retrieve the form you want to create
FORM=$(curl -s -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms/346127?format=nested)

# Modify the form as needed, example changing the name
MODIFIED_FORM=$(echo $FORM | jq '.name = "New Form Name"')

# Then, POST it to create the new form
curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d "$MODIFIED_FORM" \
  https://www.gocanvas.com/api/v3/forms
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

# First, retrieve the form you want to create
get_uri = URI("https://www.gocanvas.com/api/v3/forms/346127?format=nested")
get_req = Net::HTTP::Get.new(get_uri)
get_req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
get_req['Content-Type'] = "application/json"

form_definition = Net::HTTP.start(get_uri.hostname, get_uri.port, use_ssl: true) do |http|
  res = http.request(get_req)
  JSON.parse(res.body)
end

# Modify the form as needed, example changing the name
form_definition['name'] = 'New Form Name'

# Then, POST it to create the new form
post_uri = URI("https://www.gocanvas.com/api/v3/forms")
post_req = Net::HTTP::Post.new(post_uri)
post_req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
post_req['Content-Type'] = "application/json"
post_req.body = form_definition.to_json

res = Net::HTTP.start(post_uri.hostname, post_uri.port, use_ssl: true) do |http|
  http.request(post_req)
end

form_json = JSON.parse(res.body)

const username = "api.user@example.com";
const password = "supersecretpassword";

// First, retrieve the form you want to create
const response = await fetch(`https://www.gocanvas.com/api/v3/forms/346127?format=nested`, {
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json"
  }
});
const formDefinition = await response.json();

// Modify the form as needed, example changing the name
formDefinition.name = 'New Form Name';

// Then, POST it to create the new form
fetch(`https://www.gocanvas.com/api/v3/forms`, {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json"
  },
  body: JSON.stringify(formDefinition)
})
  .then(response => response.json())
  .then(form => console.log(form));

Users can create a new Form by sending a JSON representation of the Form definition. The JSON structure is the same as the response from retrieving a nested format of a Form.

This method's response will return the metadata format of the Form, which includes the new Form's id and root_version_id for future use.

HTTP Request

POST https://www.gocanvas.com/api/v3/forms

Request Body Parameters

The request body should be the full JSON response from a GET request (using nested format). You can retrieve an existing Form and POST it to create a new Form.

Parameter Type Description
name (required) string The name of the Form
status (required) enum The target status of the Form. Must be one of new, pending, or published
department_id* integer The Department ID for the Form
sections array Array of sections containing sheets and entries

* department_id is required when Departments are enabled for the Company.

RESPONSE

{
  "id": 346127,
  "type": "form",
  "name": "Basic Form",
  "description": null,
  "status": "published",
  "version": 1,
  "root_version_id": 346127,
  "dispatch_enabled": true,
  "workflow_enabled": false,
  "web_form": true,
  "email_options": 2,
  "view_pdf_mobile": true
}

Update a Form

# First, retrieve the form you want to update
FORM=$(curl -s -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms/346127?format=nested)

# Modify the form as needed, example changing the name
MODIFIED_FORM=$(echo $FORM | jq '.name = "Updated Form Name"')

# Then, POST it to update the form
curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d "$MODIFIED_FORM" \
  https://www.gocanvas.com/api/v3/forms/346127

require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
form_id = 346127

# First, retrieve the form you want to update
get_uri = URI("https://www.gocanvas.com/api/v3/forms/#{form_id}?format=nested")
get_req = Net::HTTP::Get.new(get_uri)
get_req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
get_req['Content-Type'] = "application/json"

form_definition = Net::HTTP.start(get_uri.hostname, get_uri.port, use_ssl: true) do |http|
  res = http.request(get_req)
  JSON.parse(res.body)
end

# Modify the form as needed, example changing the name
form_definition['name'] = 'Updated Form Name'

# Then, POST it to update the form
post_uri = URI("https://www.gocanvas.com/api/v3/forms/#{form_id}")
post_req = Net::HTTP::Post.new(post_uri)
post_req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
post_req['Content-Type'] = "application/json"
post_req.body = form_definition.to_json

res = Net::HTTP.start(post_uri.hostname, post_uri.port, use_ssl: true) do |http|
  http.request(post_req)
end

form_json = JSON.parse(res.body)

const username = "api.user@example.com";
const password = "supersecretpassword";
const formId = 346127;

// First, retrieve the form you want to update
const response = await fetch(`https://www.gocanvas.com/api/v3/forms/${formId}?format=nested`, {
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json"
  }
});
const formDefinition = await response.json();

// Modify the form as needed, example changing the name
formDefinition.name = 'Updated Form Name';

// Then, POST it to update the form
fetch(`https://www.gocanvas.com/api/v3/forms/${formId}`, {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json"
  },
  body: JSON.stringify(formDefinition)
})
  .then(response => response.json())
  .then(form => console.log(form));

Users can update an existing Form by posting the modified JSON from a GET request to the POST endpoint when a form_id is provided in the URL. This will create a new version of the Form with the provided updates. The JSON structure is the same as the response from retrieving a nested format of a Form.

This method's response will return the metadata format of the Form, which includes the new Form's id and root_version_id for future use.

HTTP Request

POST https://www.gocanvas.com/api/v3/forms/346127

Request Body Parameters

The request body should be the full JSON response from a GET request (using nested format) with your modifications applied. You can POST it to update the Form.

Parameter Type Description
name (required) string The name of the Form
status (required)** enum The target status of the Form. Must be one of pending, published, or archived
department_id* integer The Department ID for the Form
sections array Array of sections containing sheets and entries

* department_id is required when Departments are enabled for the Company.

** Allowed status transitions depend on the Form's current state. For example, archived is only valid for currently published Forms. Updating a published Form automatically creates a new version, and republishing archives the prior version.

RESPONSE

{
  "id": 346127,
  "type": "form",
  "name": "Basic Form",
  "description": null,
  "status": "published",
  "version": 1,
  "root_version_id": 346127,
  "dispatch_enabled": true,
  "workflow_enabled": false,
  "web_form": true,
  "email_options": 2,
  "view_pdf_mobile": true
}

Assigned Users for Form

User can view a list of all the Users the specified Form has been assigned to.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms/4639578/assigned_users
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/4639578/assigned_users")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

users_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/4639578/assigned_users", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(users => console.log(users));

HTTP Request

GET https://www.gocanvas.com/api/v3/forms/4639578/assigned_users

RESPONSE

[
  {
    "id": 5486,
    "type": "assigned_user",
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane.doe@gocanvas.com"
  },
  {
    "id": 5490,
    "type": "assigned_user",
    "first_name": "Smith",
    "last_name": "Kane",
    "email": "smith.kane@gocanvas.com"
  }
]

Assign User to Form

BODY='{
  user_id: 114,
  department_id: 1234
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/forms/4639578/assigned_users
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  user_id: 114,
  department_id: 1234
}

uri = URI("https://www.gocanvas.com/api/v3/forms/4639578/assigned_users")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

user_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  user_id: 114,
  department_id: 1234
};

fetch("https://www.gocanvas.com/api/v3/forms/4639578/assigned_users", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(user => console.log(user));

Users can assign another User to a Form.

HTTP Request

POST https://www.gocanvas.com/api/v3/forms/4639578/assigned_users

Parameter Type Description
user_id integer The id of the User to assign
department_id* integer (optional) The Department of the Form to assign to

* department_id must be specified when Departments are enabled for the Company.

RESPONSE

{
  "type": "assigned_user",
  "form_id": 4639578,
  "user_id": 114,
  "department_id": 1234
}

Unassign User from Form

BODY='{
  user_id: 114,
  department_id: 1234
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  -d $BODY \
  https://www.gocanvas.com/api/v3/forms/4639578/assigned_users/3310
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  user_id: 114,
  department_id: 1234
}

uri = URI("https://www.gocanvas.com/api/v3/forms/4639578/assigned_users/3310")

json_request_body = request_body.to_json
req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

user_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  user_id: 114,
  department_id: 1234
};

fetch("https://www.gocanvas.com/api/v3/forms/4639578/assigned_users/3310", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(user => console.log(user));

RESPONSE

{
    "message": "User 5652 has been unassigned from form 16043 successfully"
}

Users can unassign another User from a Form.

HTTP Request

DELELTE https://www.gocanvas.com/api/v3/forms/4639578/assigned_users/114

Parameter Type Description
user_id integer The id of the User to assign
department_id* integer (optional) The Department of the Form to assign to

* department_id must be specified when Departments are enabled for the Company.

Shared Departments for Form

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms/4639578/shared_departments
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/4639578/shared_departments")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

departments_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/4639578/shared_departments", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(departments => console.log(departments));

Users can view a list of all the Departments the specified Form has been shared with.

HTTP Request

GET https://www.gocanvas.com/api/v3/forms/4639578/shared_departments

RESPONSE

[
  {
    "id": 1234,
    "type": "department",
    "name": "First Department",
    "description": "First Department"
  },
  {
    "id": 1235,
    "type": "department",
    "name": "Second Department",
    "description": "Second Department"
  },
  {
    "id": 1236,
    "type": "department",
    "name": "Third Department",
    "description": "Third Department"
  }
]

Share Form with Departments

BODY='{
  "department_ids": [1234, 1235, 1236]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/forms/4639578/shared_departments
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "department_ids": [1234, 1235, 1236]
}

uri = URI("https://www.gocanvas.com/api/v3/forms/4639578/shared_departments")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

departments_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "department_ids": [1234, 1235, 1236]
};

fetch("https://www.gocanvas.com/api/v3/forms/4639578/shared_departments", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(departments => console.log(departments));

Users can share a Form with the specified Departments.

HTTP Request

POST https://www.gocanvas.com/api/v3/forms/4639578/shared_departments

Parameter Type Description
body JSON The JSON Submission body
body.department_ids array An Array of Department Ids to share the Form with (Max of 50)

RESPONSE

[
  {
    "id": 1234,
    "type": "department",
    "name": "First Department",
    "description": "First Department"
  },
  {
    "id": 1235,
    "type": "department",
    "name": "Second Department",
    "description": "Second Department"
  },
  {
    "id": 1236,
    "type": "department",
    "name": "Third Department",
    "description": "Third Department"
  }
]

Delete a Form

A Form can be deleted with a DELETE request.

By default, the DELETE request will soft-delete the Form, which preserves the Form data but hides it from all views. To permanently delete a Form, use the hard_delete=true parameter, e.g. DELETE https://www.gocanvas.com/api/v3/forms/346127?hard_delete=true.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/forms/346127
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/346127")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

form_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/346127", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(form => console.log(form));

RESPONSE

{
  "message": "Form 346127 has been soft deleted successfully"
}

HTTP Request

DELETE https://www.gocanvas.com/api/v3/forms/346127

Request Parameters

Parameter Type Description
hard_delete* boolean Will hard delete the Form record when set to true

* This is an optional URL parameter. If not provided, the Form will be soft deleted.

In addition to removing the Form record itself, a hard delete will also permanently delete the following associated data:

Group

Groups allow for the organization of users and can be assigned Forms. Groups are a useful way to organize teams, job functions, or common workflows and manage Form assignments in one place rather than individually assigning Forms to each User. Learn more about GoCanvas Groups.

The Group object

EXAMPLE

{
  "id": 1873,
  "type": "group",
  "department_id": 21474,
  "created_at": "2025-06-03T17:39:39Z",
  "name": "Inspectors",
  "description": "Common tasks for inspectors",
  "members": [
    {
      "id": 20079,
      "type": "user",
      "enabled": true,
      "login": "charles.neverdon@example.com"
    }
  ],
  "assigned_forms": [
    {
      "id": 80531,
      "type": "form",
      "name": "Site Evaluation",
      "description": null,
      "status": "published",
      "version": 6,
      "root_version_id": 80526
    },
    {
      "id": 81531,
      "type": "form",
      "name": "Hazard Assessment",
      "description": null,
      "status": "published",
      "version": 24,
      "root_version_id": 74915
    },
    {
      "id": 43671,
      "type": "form",
      "name": "Timecard",
      "description": null,
      "status": "published",
      "version": 2,
      "root_version_id": 34544
    }
  ]
}

Groups may have a helpful name and description to identify the Group's purpose. Groups exist within a specific Department. Group members are Users and assigned_forms are Forms that are assigned to the Group.

List all Groups

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/groups
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/groups")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

groups_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/groups", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(groups => console.log(groups));

Users can view and filter a list of Groups.

RESPONSE

[
  {
    "id": 1873,
    "type": "group",
    "department_id": 21474,
    "created_at": "2025-06-04T00:12:02Z",
    "name": "Inspectors",
    "description": "Common tasks for inspectors"
  },
  {
    "id": 1891,
    "type": "group",
    "department_id": 21474,
    "created_at": "2025-06-04T00:52:26Z",
    "name": "General Contractors",
    "description": "GCs, subcontractors, and other workers"
  }
]

HTTP Request

GET https://www.gocanvas.com/api/v3/groups

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1
department_id* integer (optional) The identifier for the Department associated with the Group (default department*)

* If no department_id is provided, the User's default department will be used.

Retrieve a Group

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/groups/1873
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/groups/1873")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

group_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/groups/1873", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(group => console.log(group));

Users can retrieve a Group by its ID.

RESPONSE

{
  "id": 1873,
  "type": "group",
  "department_id": 21474,
  "created_at": "2025-06-03T17:39:39Z",
  "name": "Inspectors",
  "description": "Common tasks for inspectors",
  "members": [
    {
      "id": 20079,
      "type": "user",
      "enabled": true,
      "login": "charles.neverdon@example.com"
    }
  ],
  "assigned_forms": [
    {
      "id": 80531,
      "type": "form",
      "name": "Site Evaluation",
      "description": null,
      "status": "published",
      "version": 6,
      "root_version_id": 80526
    },
    {
      "id": 81531,
      "type": "form",
      "name": "Hazard Assessment",
      "description": null,
      "status": "published",
      "version": 24,
      "root_version_id": 74915
    },
    {
      "id": 43671,
      "type": "form",
      "name": "Timecard",
      "description": null,
      "status": "published",
      "version": 2,
      "root_version_id": 34544
    }
  ]
}

HTTP Request

GET https://www.gocanvas.com/api/v3/groups/1873

Response Parameters

Parameter Type Description
id integer The identifier for this Group
department_id integer The Department the Group is associated with
name string A short string value for name of the Group
description string A longer string value describing the Group
created_at datetime The time the Group was created
members array An array of Users that are members of the Group
members[].id integer The unique User id
members[].enabled boolean Whether a user is allowed to login
members[].login string The email address of the User
assigned_forms array An array of Forms that are assigned to the Group
assigned_forms[].id integer The identifier for this exact version of the Form
assigned_forms[].name string The name of the Form
assigned_forms[].status * enum The status of the Form.
Can be new, pending, published, archived, or testing
assigned_forms[].version integer The version number of the Form. When a new version is saved and published, this version counter increments
assigned_forms[].root_version_id integer The original Form identifier for all versions of the Form

Create a Group

BODY='{
  name: "General Contractors",
  description: "GCs, subcontractors, and other workers"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/groups
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  name: "General Contractors",
  description: "GCs, subcontractors, and other workers"
}

uri = URI("https://www.gocanvas.com/api/v3/groups")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

group_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  name: "General Contractors",
  description: "GCs, subcontractors, and other workers"
};

fetch("https://www.gocanvas.com/api/v3/groups", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(group => console.log(group));

RESPONSE

{
  "id": 1891,
  "type": "group",
  "department_id": 21474,
  "created_at": "2025-06-04T00:52:26Z",
  "name": "General Contractors",
  "description": "GCs, subcontractors, and other workers",
  "members": [],
  "assigned_forms": []
}

To create a new Group, the POST body can be sent as JSON.

Form and User assignments can be added with Update a Group or with the Assign Form to Group and Assign User to Group endpoints.

HTTP Request

POST https://www.gocanvas.com/api/v3/groups

Request Body Parameters

Parameter Type Description
name string A short string value for name of the Group
description string A longer string value to describe the Group
department_id* integer The Department the Group is associated with

* if no department_id is provided, the Group will be associated with the User's default department

Update a Group

BODY='{
  name: "Inspectors",
  description: "Common tasks for inspectors",
  members: [
    {
      "id": 20079,
      "login": "charles.neverdon@example.com"
    }
  ],
  assigned_forms: [
    {
      "id": 80531,
      "root_version_id": 80526
    },
    {
      "root_version_id": 74915
    },
    {
      "id": 43671
    }
  ],
  send_notification: true
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X PATCH \
  -d $BODY \
  https://www.gocanvas.com/api/v3/groups
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  name: "Inspectors",
  description: "Common tasks for inspectors",
  members: [
    {
      "id": 20079,
      "login": "charles.neverdon@example.com"
    }
  ],
  assigned_forms: [
    {
      "id": 80531,
      "root_version_id": 80526
    },
    {
      "root_version_id": 74915
    },
    {
      "id": 43671
    }
  ],
  send_notification: true
}

uri = URI("https://www.gocanvas.com/api/v3/groups")

json_request_body = request_body.to_json
req = Net::HTTP::Patch.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

group_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  name: "Inspectors",
  description: "Common tasks for inspectors",
  members: [
    {
      "id": 20079,
      "login": "charles.neverdon@example.com"
    }
  ],
  assigned_forms: [
    {
      "id": 80531,
      "root_version_id": 80526
    },
    {
      "root_version_id": 74915
    },
    {
      "id": 43671
    }
  ],
  send_notification: true
};

fetch("https://www.gocanvas.com/api/v3/groups", {
  method: "PATCH",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(group => console.log(group));

RESPONSE

{
  "id": 1873,
  "type": "group",
  "department_id": 21474,
  "created_at": "2025-06-03T17:39:39Z",
  "name": "Inspectors",
  "description": "Common tasks for inspectors",
  "members": [
    {
      "id": 20079,
      "type": "user",
      "enabled": true,
      "login": "charles.neverdon@example.com"
    }
  ],
  "assigned_forms": [
    {
      "id": 80531,
      "type": "form",
      "name": "Site Evaluation",
      "description": null,
      "status": "published",
      "version": 6,
      "root_version_id": 80526
    },
    {
      "id": 81531,
      "type": "form",
      "name": "Hazard Assessment",
      "description": null,
      "status": "published",
      "version": 24,
      "root_version_id": 74915
    },
    {
      "id": 43671,
      "type": "form",
      "name": "Timecard",
      "description": null,
      "status": "published",
      "version": 2,
      "root_version_id": 34544
    }
  ]
}

A group that has already been created can be updated by sending a PATCH request to the group endpoint with the group ID. Groups can not be moved to a different department as Users and Forms are assigned to a group within a specific department.

Form and User assignments updated with this endpoint will overwrite any existing assignments. To add Forms or Users to a Group without overwriting existing assignments, use the Assign Form to Group and Assign User to Group endpoints.

HTTP Request

PATCH https://www.gocanvas.com/api/v3/groups/1873

Request Body Parameters

Parameter Type Description Default
name string (optional) A short string value for name of the Group
description string (optional) A longer string value to describe the Group
members array (optional) An array of Users to overwrite the current members with
Omit members to leave unchanged
Pass an empty array ([]) to remove all members.
members[].id* integer (optional) The unique User id
members[].login* string (optional) The email address of the User
assigned_forms array (optional) An array of Forms to overwrite the current assigned forms with
Omit assigned_forms to leave unchanged
Pass an empty array ([]) to remove all assigned forms.
assigned_forms[].id** integer (optional) The identifier for the Form to assign to the Group
assigned_forms[].root_version_id** integer (optional) The root_version_id for the Form to assign to the Group.
This will assign the latest published version of the Form.
send_notification boolean (optional) When true, a notification will be sent to affected users when their group membership or new form assignments are created.
Notification settings configured by users or at the account level are respected, refer to Change GoCanvas Notification Settings
false

* One of id or login is required for each members[]

** One of id or root_version_id is required for each assigned_forms[]

Delete a Group

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/groups/1874
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/groups/1874")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

group_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/groups/1874", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(group => console.log(group));

RESPONSE

{
  "message": "Group 1874 has been deleted successfully"
}

A Group can be deleted with a DELETE request. Group deletions are permanent.

HTTP Request

DELETE https://www.gocanvas.com/api/v3/groups/1874

Assign Form to Group

BODY='{
  "id": 80531,
  "root_version_id": 80526,
  "send_notification": true
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/groups/1874/forms
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "id": 80531,
  "root_version_id": 80526,
  "send_notification": true
}

uri = URI("https://www.gocanvas.com/api/v3/groups/1874/forms")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

user_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "id": 80531,
  "root_version_id": 80526,
  "send_notification": true
};

fetch("https://www.gocanvas.com/api/v3/groups/1874/forms", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(user => console.log(user));

RESPONSE

{
  "message": "Form assigned to group successfully",
}

Forms can be assigned to a Group individually.

HTTP Request

POST https://www.gocanvas.com/api/v3/groups/1874/forms

Request Body Parameters

Parameter Type Description Default
id* integer (optional) The identifier for the Form to assign to the Group
root_version_id* integer (optional) The root_version_id for the Form to assign to the Group.
This will assign the latest published version of the Form.
send_notification boolean (optional) When true, a notification will be sent to group members about the newly assigned form.
Notification settings configured by users or at the account level are respected, refer to Change GoCanvas Notification Settings
false

* One of id or root_version_id is required for each assigned_forms[]

Remove Form from Group

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/groups/1874/forms/80531
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/groups/1874/forms/80531")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

users_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/groups/1874/forms/80531", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(users => console.log(users));

RESPONSE

{
  "message": "Form removed from group successfully",
}

Forms can be removed from a Group individually.

HTTP Request

DELETE https://www.gocanvas.com/api/v3/groups/1874/forms/80531

Assign User to Group

BODY='{
  "id": 20079,
  "login": "charles.neverdon@example.com",
  "send_notification": true
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/groups/1874/users
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "id": 20079,
  "login": "charles.neverdon@example.com",
  "send_notification": true
}

uri = URI("https://www.gocanvas.com/api/v3/groups/1874/users")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

user_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "id": 20079,
  "login": "charles.neverdon@example.com",
  "send_notification": true
};

fetch("https://www.gocanvas.com/api/v3/groups/1874/users", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(user => console.log(user));

RESPONSE

{
  "message": "User assigned to group successfully",
}

Users can be assigned to a Group individually.

HTTP Request

POST https://www.gocanvas.com/api/v3/groups/1874/users

Request Body Parameters

Parameter Type Description Default
id* integer (optional) The identifier for the User to assign to the Group
login* string (optional) The email address of the User to assign to the Group
send_notification boolean (optional) When true, a notification will be sent to the user about being added to the group.
Notification settings configured by users or at the account level are respected, refer to Change GoCanvas Notification Settings
false

* Either User's id or login must be provided.

Remove User from Group

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/groups/1874/users/20079
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/groups/1874/users/20079")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

users_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/groups/1874/users/20079", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(users => console.log(users));

RESPONSE

{
  "message": "User removed from group successfully",
}

Users can be removed from a Group individually.

HTTP Request

DELETE https://www.gocanvas.com/api/v3/groups/1874/users/20079

Me

Current User Profile

The /me endpoint is useful for OAuth-authenticated applications to verify the current token's user information and retrieve basic profile data. It can also be helpful to retrieve company_id and default_department_id for subsequent API calls.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/me
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/me")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

profile_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/me", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(profile => console.log(profile));

HTTP Request

GET https://www.gocanvas.com/api/v3/me

RESPONSE

{
  "id": 20122,
  "type": "user",
  "first_name": "John",
  "last_name": "Doe",
  "login": "john.doe@example.com",
  "phone": "555-123-4567",
  "address": "123 Main St",
  "address2": "Suite 200",
  "city": "Denver",
  "state": "CO",
  "zip": "80202",
  "enabled": true,
  "created_at": "2023-06-15T10:30:45.000-04:00",
  "company_id": 1999,
  "company_name": "Example Company",
  "default_department_id": 5678,
  "default_department_name": "Operations"
}

Response Parameters

Parameter Type Description
id integer The identifier for this User
type string The type of the object
first_name string The first name of the User
last_name string The last name of the User
login string The login/email address of the User
phone string The phone number of the User
address string The street address of the User
address2 string The second line of the User's street address
city string The city of the User
state string The state or province of the User
zip string The postal code of the User
enabled boolean Whether the User is allowed to login
created_at datetime The date and time when the User was created
company_id integer The identifier for the User's Company
company_name string The name of the User's Company
default_department_id integer The identifier for the User's default Department
default_department_name string The name of the User's default Department

Project

A Project is created and used to track the progress of a specific task or job. A Project is associated with a Department, and optionally a Customer and Site. A Project can have a status of active, inactive, or draft.

The Project object

EXAMPLE

{
  "id": 11,
  "name": "My new Project",
  "company_id": 135196,
  "department_id": 21974,
  "customer_id": 25,
  "site_id": 6,
  "start_date": "2024-10-16 11:30:00 UTC",
  "end_date": null,
  "status": "active",
  "notes": "House renovation",
  "code": "NEW00001"
}

A Project requires a name to be created. The name is the only required field. When creating a Project, the user needs to be authorized to access the Department to which the Project is associated.

List all Projects

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/projects
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/projects")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

projects_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/projects", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(projects => console.log(projects));

Users can view a list of all the Projects for a specific department to which they have access.

RESPONSE

[
  {
    "id": 11,
    "name": "My new Project",
    "company_id": 135196,
    "department_id": 21974,
    "customer_id": 25,
    "site_id": 6,
    "start_date": "2023-10-01 00:00:00 UTC",
    "end_date": null,
    "status": "active",
    "notes": "House renovation",
    "code": "NEW00001"
  },
  {
    "id": 12,
    "name": "Swimming Pool Project",
    "company_id": 135196,
    "department_id": 21974,
    "customer_id": null,
    "site_id": null,
    "start_date": "2023-10-01 00:00:00 UTC",
    "end_date": "2023-12-31 00:00:00 UTC",
    "status": "active",
    "notes": "Below ground swimming pool",
    "code": "PRO033"
  },
  {
    "id": 13,
    "name": "Remodel Project",
    "company_id": 135196,
    "department_id": 21974,
    "customer_id": null,
    "site_id": null,
    "start_date": "2023-10-01 00:00:00 UTC",
    "end_date": "2023-12-31 00:00:00 UTC",
    "status": "active",
    "notes": "House remodel",
    "code": "NEW0443"
  }
]

HTTP Request

GET https://www.gocanvas.com/api/v3/projects

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1

Retrieve a Project

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/projects/11
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/projects/11")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

project_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/projects/11", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(project => console.log(project));

Users can retrieve a Project by its ID.

HTTP Request

GET https://www.gocanvas.com/api/v3/projects/11

RESPONSE

{
  "id": 11,
  "name": "My new Project",
  "company_id": 135196,
  "department_id": 21974,
  "customer_id": 25,
  "site_id": 6,
  "start_date": "2024-10-16 11:30:00 UTC",
  "end_date": null,
  "status": "active",
  "notes": "House renovation",
  "code": "NEW00001"
}

Response Parameters

Parameter Type Description
id integer The identifier for this exact Project
name string A short string value for name of the Project
company_id integer The Company the Project is associated with
department_id integer The Department the Project is associated with
customer_id integer The Customer the Project is associated with
site_id integer The Site the Project is associated with
start_date string A DateTime value of when the Project starts
end_date string A Datetime value of when the Project concludes
status enum The status of the Project. Can be active, inactive, or draft
notes string A longer string value to describe the Project
code string An alpha numeric code to uniquely identify the Project

Create a Project

To create a new Project, the POST body can be sent as JSON. The only required field is the name of the Project.

BODY='{
  "name": "My newly created Project",
  "status": "draft",
  "customer_id": 25,
  "site_id": 6,
  "start_date": "2024-10-01T11:30:00"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/projects
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "name": "My newly created Project",
  "status": "draft",
  "customer_id": 25,
  "site_id": 6,
  "start_date": "2024-10-01T11:30:00"
}

uri = URI("https://www.gocanvas.com/api/v3/projects")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

project_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "name": "My newly created Project",
  "status": "draft",
  "customer_id": 25,
  "site_id": 6,
  "start_date": "2024-10-01T11:30:00"
};

fetch("https://www.gocanvas.com/api/v3/projects", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(project => console.log(project));

RESPONSE

{
  "id": 21,
  "name": "My newly created Project",
  "company_id": 135196,
  "department_id": 21974,
  "customer_id": 25,
  "site_id": 6,
  "start_date": "2024-10-01 11:30:00 UTC",
  "end_date": null,
  "status": "draft",
  "code": "GAR00001"
}

HTTP Request

POST https://www.gocanvas.com/api/v3/projects

Request Body Parameters

Parameter Type Description
name* string A short string value for name of the Project
department_id** integer The Department the Project is associated with
customer_id*** integer The ID of a Customer to associate to the Project
site_id* integer The ID of a site related to a Customer
start_date**** integer A DateTime value of when the Project starts
end_date**** integer A Datetime value of when the Project concludes
status enum The status of the Project. Can be active, inactive, or draft
notes string A longer string value to describe the Project
code string An alpha numeric code to uniquely identify the Project

* required field

** if no department_id is provided, the Project will be associated with the User's default department

*** make sure that the customer_id and site_id provided are associated with eachother

**** start_date and end_date must be in the ISO-8601 format, e.g. 2024-01-30 or 2024-01-30T23:59:59 or 2024-01-30T23:59:59-04:00

Update a Project

To update an existing Project, the PATCH request body can be sent as JSON.

BODY='{
  "status": "active",
  "customer_id": null,
  "site_id": null,
  "start_date": "2024-10-16T11:30:00",
  "notes": "Garage renovation"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X PATCH \
  -d $BODY \
  https://www.gocanvas.com/api/v3/projects
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "status": "active",
  "customer_id": null,
  "site_id": null,
  "start_date": "2024-10-16T11:30:00",
  "notes": "Garage renovation"
}

uri = URI("https://www.gocanvas.com/api/v3/projects")

json_request_body = request_body.to_json
req = Net::HTTP::Patch.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

project_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "status": "active",
  "customer_id": null,
  "site_id": null,
  "start_date": "2024-10-16T11:30:00",
  "notes": "Garage renovation"
};

fetch("https://www.gocanvas.com/api/v3/projects", {
  method: "PATCH",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(project => console.log(project));

RESPONSE

{
  "message": "Project updated successfully"
}

HTTP Request

PATCH https://www.gocanvas.com/api/v3/projects/21

Request Body Parameters

Parameter Type Description
name* string A short string value for name of the Project
department_id** integer The Department the Project is associated with
customer_id*** integer The ID of a Customer to associate to the Project
site_id* integer The ID of a site related to a Customer
start_date**** integer A DateTime value of when the Project starts
end_date**** integer A Datetime value of when the Project concludes
status enum The status of the Project. Can be active, inactive, or draft
notes string A longer string value to describe the Project
code string An alpha numeric code to uniquely identify the Project

* required field

** if no department_id is provided, the Project will be associated with the User's default department

*** make sure that the customer_id and site_id provided are associated with eachother

**** start_date and end_date must be in the ISO-8601 format, e.g. 2024-01-30 or 2024-01-30T23:59:59 or 2024-01-30T23:59:59-04:00

Delete a Project

A Project can be deleted with a DELETE request.

By default, the DELETE request will soft-delete the project, which preserves the Project data but hides it from the web views. To permanently delete a Project, use the hard_delete=true parameter, e.g. DELETE https://www.gocanvas.com/api/v3/projects/21?hard_delete=true.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/projects/21
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/projects/21")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

project_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/projects/21", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(project => console.log(project));

RESPONSE

{
  "message": "Project 21 has been soft deleted successfully"
}

HTTP Request

DELETE https://www.gocanvas.com/api/v3/projects/21

Request Parameters

Parameter Type Description
hard_delete* boolean Will hard delete the Project record when set to true

* This is an optional URL parameter. If not provided, the Project will be soft deleted.

Reference Data

Reference Data is data that is used to populate dropdowns, checkboxes, and other controls in a Form. The two main purposes of Reference Data are to:

  1. Provide a list of options for a user to select from when filling out a Form.
  2. Auto-populate fields based on user input to other fields by looking up other values in the Reference Data rows.

The Reference Data object

EXAMPLE

{
  "id": 10761,
  "type": "reference_data",
  "name": "US Zip Codes",
  "description": null,
  "use_user_groups": null,
  "version": 1,
  "department_id": 21474,
  "headers": ["City", "ZIP Code", "County", "State"],
  "rows": [
    [ "Jones", "36749", "Autauga", "Alabama" ],
    [ "Daphne", "36526", "Baldwin", "Alabama" ],
    [ "Spanish Forst", "36527", "Baldwin", "Alabama" ],
    [ "Brent", "35034", "Bibb", "Alabama" ],
    [ "Birmingham", "35201", "Bibb", "Alabama" ],
    [ "Birmingham", "35202", "Bibb", "Alabama" ],
    [ "Dinwiddie", "23841", "Dinwiddie", "Virginia" ]
  ]
}

Reference Data is structured similar to a spreadsheet, with a set of headers and rows. The order of the headers aligns to the order of each row of data.

Property Type Description
id integer The unique reference data id
name string A short string value for name of a reference data
description string A longer string value describing a reference data
use_user_groups boolean Whether the reference data is shared with all users or only users in the same group
version integer The version of the reference data
department_id integer The unique department id
headers array An array of strings that represent the headers of the reference data
rows array An array of arrays that represent the rows of the reference data

List all Reference Data

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/reference_data
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/reference_data")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

reference_data_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/reference_data", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
})
  .then(response => response.json())
  .then(referenceData => console.log(referenceData));

Users can view a list of all the reference data associated with their Company.

HTTP Request

GET https://www.gocanvas.com/api/v3/reference_data

Request Parameters

Property Type Description
department_id* integer (optional) The unique Department id

* If Departments are enabled for the Company, a URL parameter can be provided to list the Reference Data associated with that specific Department. If no department_id is provided, the Reference Data associated with the User's default department.

RESPONSE

[
  {
    "id": 10760,
    "type": "reference_data",
    "name": "US State Abbreviations",
    "description": null,
    "column_count": 2,
    "use_user_groups": null,
    "version": 27,
    "department_id": 21474
  }
  {
    "id": 10761,
    "type": "reference_data",
    "name": "US Zip Codes",
    "description": null,
    "column_count": 4,
    "use_user_groups": null,
    "version": 1,
    "department_id": 21474
  }
]

Retrieve a Reference Data

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/reference_data/10761?format=rows_with_index
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/reference_data/10761?format=rows_with_index")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

reference_data_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/reference_data/10761?format=rows_with_index", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
})
  .then(response => response.json())
  .then(referenceData => console.log(referenceData));

Users can view a specific Reference Data by its id.

HTTP Request

GET https://www.gocanvas.com/api/v3/reference_data/10761

RESPONSE

{
  "id": 10761,
  "type": "reference_data",
  "name": "US Zip Codes",
  "description": null,
  "use_user_groups": null,
  "version": 1,
  "department_id": 21474,
  "headers": ["gc_row_index", "City", "ZIP Code", "County", "State"],
  "rows": [
    [ "0", "Jones", "36749", "Autauga", "Alabama" ],
    [ "1", "Daphne", "36526", "Baldwin", "Alabama" ],
    [ "2", "Spanish Forst", "36527", "Baldwin", "Alabama" ],
    [ "3", "Brent", "35034", "Bibb", "Alabama" ],
    [ "4", "Birmingham", "35201", "Bibb", "Alabama" ],
    [ "5", "Birmingham", "35202", "Bibb", "Alabama" ],
    [ "6", "Dinwiddie", "23841", "Dinwiddie", "Virginia" ]
  ]
}

Request Parameters

Parameter Type Description
format * enum The format of the returned reference data in JSON.
Can be rows or rows_with_index

* If format is not specified, the default format is rows. If format is specified as rows_with_index, the returned reference data will include an additional header of gc_row_index and each row will include an additional item of its numerical index.

Create Reference Data

BODY='{
  "name": "US Zip Codes",
  "headers": ["City", "ZIP Code", "County", "State"],
  "rows": [
    ["Jones", "36749", "Autauga", "Alabama"],
    ["Daphne", "36526", "Baldwin", "Alabama"],
    ["Spanish Forst", "36527", "Baldwin", "Alabama"],
    ["Brent", "35034", "Bibb", "Alabama"],
    ["Birmingham", "35201", "Bibb", "Alabama"],
    ["Birmingham", "35202", "Bibb", "Alabama"],
    ["Dinwiddie", "23841", "Dinwiddie", "Virginia"]
  ]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/reference_data
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "name": "US Zip Codes",
  "headers": ["City", "ZIP Code", "County", "State"],
  "rows": [
    ["Jones", "36749", "Autauga", "Alabama"],
    ["Daphne", "36526", "Baldwin", "Alabama"],
    ["Spanish Forst", "36527", "Baldwin", "Alabama"],
    ["Brent", "35034", "Bibb", "Alabama"],
    ["Birmingham", "35201", "Bibb", "Alabama"],
    ["Birmingham", "35202", "Bibb", "Alabama"],
    ["Dinwiddie", "23841", "Dinwiddie", "Virginia"]
  ]
}

uri = URI("https://www.gocanvas.com/api/v3/reference_data")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

reference_data_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "name": "US Zip Codes",
  "headers": ["City", "ZIP Code", "County", "State"],
  "rows": [
    ["Jones", "36749", "Autauga", "Alabama"],
    ["Daphne", "36526", "Baldwin", "Alabama"],
    ["Spanish Forst", "36527", "Baldwin", "Alabama"],
    ["Brent", "35034", "Bibb", "Alabama"],
    ["Birmingham", "35201", "Bibb", "Alabama"],
    ["Birmingham", "35202", "Bibb", "Alabama"],
    ["Dinwiddie", "23841", "Dinwiddie", "Virginia"]
  ]
};

fetch("https://www.gocanvas.com/api/v3/reference_data", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(reference_data => console.log(reference_data));

Users can create new Reference Data. New Reference Data must have a unique name.

HTTP Request

POST https://www.gocanvas.com/api/v3/reference_data

RESPONSE

{
  "id": 10761,
  "type": "reference_data",
  "name": "US Zip Codes",
  "description": null,
  "use_user_groups": null,
  "version": 1,
  "department_id": 21474,
  "headers": ["gc_row_index", "City", "ZIP Code", "County", "State"],
  "rows": [
    [ "0", "Jones", "36749", "Autauga", "Alabama" ],
    [ "1", "Daphne", "36526", "Baldwin", "Alabama" ],
    [ "2", "Spanish Forst", "36527", "Baldwin", "Alabama" ],
    [ "3", "Brent", "35034", "Bibb", "Alabama" ],
    [ "4", "Birmingham", "35201", "Bibb", "Alabama" ],
    [ "5", "Birmingham", "35202", "Bibb", "Alabama" ],
    [ "6", "Dinwiddie", "23841", "Dinwiddie", "Virginia" ]
  ]
}

Request Parameters

Parameter Type Description
format * enum The format of the returned reference data in JSON.
Can be rows or rows_with_index

* If format is not specified, the default format is rows. If format is specified as rows_with_index, the returned reference data will include an additional header of gc_row_index and each row will include an additional item of its numerical index.

Request Body Parameters

Parameter Type Description
name string A short string value for name of a new reference data
description string A longer string value describing a new reference data
department_id* integer (optional) The unique Department ID to assign a new reference data to a Department
headers array An array of strings that represent the headers of the reference data
rows array An array of arrays that represent the rows of the reference data

* department_id is required when creating a new Reference Data object if Departments are enabled for the Company.

Update Reference Data

BODY='{
  "headers": ["gc_row_index", "City", "ZIP Code", "County", "State"],
  "rows": [
    ["2", "Spanish Fort", "36527", "Baldwin", "Alabama"]
  ],
  "delete_rows": ["6"]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X PATCH \
  -d $BODY \
  https://www.gocanvas.com/api/v3/reference_data
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "headers": ["gc_row_index", "City", "ZIP Code", "County", "State"],
  "rows": [
    ["2", "Spanish Fort", "36527", "Baldwin", "Alabama"]
  ],
  "delete_rows": ["6"]
}

uri = URI("https://www.gocanvas.com/api/v3/reference_data")

json_request_body = request_body.to_json
req = Net::HTTP::Patch.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

reference_data_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "headers": ["gc_row_index", "City", "ZIP Code", "County", "State"],
  "rows": [
    ["2", "Spanish Fort", "36527", "Baldwin", "Alabama"]
  ],
  "delete_rows": ["6"]
};

fetch("https://www.gocanvas.com/api/v3/reference_data", {
  method: "PATCH",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(reference_data => console.log(reference_data));

Users have the ability to update Reference Data for a specified Company. The default format is rows_with_index. The returned reference data will include an additional header of gc_row_index and each row will include an additional item of its numerical index.

Users may update existing rows by providing a gc_row_index with the row to identify the row to update.
Users may add new rows by either providing a gc_row_index of a blank string ("") or by omitting the gc_row_index column.
Users may delete existing rows by passing an array of indexes corresponding with the gc_row_index of the row.

Users should use the rows_with_index format option when retrieving Reference Data to understand the indexes created by GoCanvas.

HTTP Request

PATCH https://www.gocanvas.com/api/v3/reference_data/10761

RESPONSE

{
  "id": 10761,
  "type": "reference_data",
  "name": "US Zip Codes",
  "description": null,
  "use_user_groups": null,
  "version": 2,
  "department_id": 21474,
  "headers": ["gc_row_index", "City", "ZIP Code", "County", "State"],
  "rows": [
    [ "0", "Jones", "36749", "Autauga", "Alabama" ],
    [ "1", "Daphne", "36526", "Baldwin", "Alabama" ],
    [ "2", "Spanish Fort", "36527", "Baldwin", "Alabama" ],
    [ "3", "Brent", "35034", "Bibb", "Alabama" ],
    [ "4", "Birmingham", "35201", "Bibb", "Alabama" ],
    [ "5", "Birmingham", "35202", "Bibb", "Alabama" ]
  ]
}

Request Body Parameters

Parameter Type Description
headers array An array of strings that represent the headers of the reference data
rows array An array of arrays that represent the rows of the reference data to be updated or added
delete_rows array (optional) An array of integers of rows indexes to delete from the reference data

Report

Reports assemble Submission data in the desired presentation format (e.g. a PDF) according to their Report Definition.

The Report object

Forms and Submissions may have multiple Report Definitions. Each Report Definition will transform data captured within a Submission into the defined format specified by a provided Report Definition identifier.

For example, a Submission with two Report Definitions could have one definition for an executive summary and one for a full report.

Retrieve the Standard Report

The Standard Report is automatically created for you by default. This is a basic Report with no customized options.

curl -u api.user@example.com:supersecretpassword \
  https://www.gocanvas.com/api/v3/submissions/162888280/standard_pdf

HTTP Request

GET https://www.gocanvas.com/api/v3/submissions/160504422/standard_pdf

Retrieve the Default Report

The default Report format is specified by default PDF options

The id field returned by creating a Submission can be used to retrieve the default Report via https://www.gocanvas.com/api/v3/submissions/[SUBMISSION_ID]/pdf

curl -u api.user@example.com:supersecretpassword \
  https://www.gocanvas.com/api/v3/submissions/162888280/pdf

HTTP Request

GET https://www.gocanvas.com/api/v3/submissions/160504422/pdf

List of Reports by Form

Forms can be associated with multiple Report Definitions (which are used to generate specific Reports, such as pdf output). This endpoint will return all the Reports currently associated with a particular Form:

GET https://www.gocanvas.com/api/v3/forms/346127/reports

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms/346127/reports
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/346127/reports")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

reports_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/346127/reports", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(reports => console.log(reports));

RESPONSE

[
  {
    "id": 7346,
    "type": "form_report_definition",
    "form_id": 346127,
    "name": "Designer",
    "created_at": "2021-09-22 19:34:17 UTC",
    "updated_at": "2021-09-22 19:34:17 UTC",
    "format": "PDF",
    "default_emailed": true
  }
]

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1

Single Report by Form

You can get more detail on a specific Report (including the full definition file) by supplying an id:

GET https://www.gocanvas.com/api/v3/forms/346127/reports/7346

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms/346127/reports/7346
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/346127/reports/7346")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

report_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/346127/reports/7346", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(report => console.log(report));
{
  "id": 7346,
  "type": "form_report_definition",
  "form_id": 346127,
  "name": "Designer",
  "definition": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<report xmlns=\"http://www.eclipse.org/birt/2005/design\" version=\"3.2.23\" id=\"1\">\n    <data-sources>\n        <oda-data-source extensionID=\"org.eclipse.birt.report.data.oda.xml\" name=\"75e0e90b-520a-424c-aa71-7658b22fc4e8\" id=\"4\">\n            <property name=\"FILELIST\">empty_submission.xml</property>\n        </oda-data-source>\n    </data-sources>\n    <data-sets>\n        <oda-data-set extensionID=\"org.eclipse.birt.report.data.oda.xml.dataSet\" name=\"75e0e90b-520a-424c-aa71-7658b22fc4e8\" id=\"5\">\n            <property name=\"dataSource\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n            <xml-property name=\"queryText\"><![CDATA[table0#-TNAME-#table0#:#[//Submissions/Submission[1]]#:#{16d4ee9f-b632-45d6-989b-79e8c54b4e36;STRING;//Form/HideConditionalScreen},{bc966d19-d769-445f-b182-2305410553a4;STRING;//Response[@Guid=\"D2E41E105EC47DA8468888CCBC663CB31301506B\"]/Value},{900ead6b-06d2-4e15-898e-5384983c454b;STRING;//Response[@Guid=\"D2E41E105EC47DA8468888CCBC663CB31301506B\"]/Displayed},{2d5647b7-c166-4ec8-8e41-4fb8b43f8fad;STRING;//Response[@Guid=\"D2E41E105EC47DA8468888CCBC663CB31301506B\"]/PDFVisible},{6d0ab69f-16fd-4aca-b2e1-b35938d794ba;STRING;//Form/HideConditionalScreen},{b6601e1a-25cd-4a06-a920-c2993757ca8a;STRING;ResponseID},{0c55f802-e5a3-4b49-970d-679e21920c56;STRING;//Form/HideConditionalScreen},{3089bd7c-0287-4d56-86b1-e21a52e34e6c;STRING;//Form/HideConditionalScreen},{652bb715-39fd-4c9f-b328-1c4650ae5c90;STRING;//Response[@Guid=\"8A9C06D355AE7B762B5CE11CE99135EC9CD486AE\"]/Value},{12a83f67-6234-494b-ad66-82f7d515afcb;STRING;//Response[@Guid=\"8A9C06D355AE7B762B5CE11CE99135EC9CD486AE\"]/Displayed},{7e6a9d44-3791-49d1-8ab2-0aaec42b1394;STRING;//Response[@Guid=\"8A9C06D355AE7B762B5CE11CE99135EC9CD486AE\"]/PDFVisible},{18a0b3d2-f9fa-4fde-97f3-f50d3a013c99;STRING;//Response[@Guid=\"15915D3CAC4DD89B98363A5BB8D776C87E7FDD13\"]/Value},{62cf2d6a-b714-41ee-97be-5a6153430d3b;STRING;//Response[@Guid=\"15915D3CAC4DD89B98363A5BB8D776C87E7FDD13\"]/Displayed},{4a6abda6-d3f7-4431-afec-939d270d0967;STRING;//Response[@Guid=\"15915D3CAC4DD89B98363A5BB8D776C87E7FDD13\"]/PDFVisible},{1e90160e-f503-4d84-999b-a36540841a8c;STRING;//Response[@Guid=\"1E5EDE84EBBD1B86F5BA57790DB8F71B5F528257\"]/Value},{52ab588a-d9d3-4613-b22f-6c989a9b3bed;STRING;//Response[@Guid=\"1E5EDE84EBBD1B86F5BA57790DB8F71B5F528257\"]/Displayed},{f40ff177-4d8e-4707-8fa1-1ecccd44671f;STRING;//Response[@Guid=\"1E5EDE84EBBD1B86F5BA57790DB8F71B5F528257\"]/PDFVisible},{91961290-f362-452d-b90d-8966733e7d3c;STRING;//Response[@Guid=\"9EFF80B7EC8D8B520CD11B988B5825D669AD05FE\"]/Value},{e9a3b434-9ba4-464e-ade7-a68272b34372;STRING;//Response[@Guid=\"9EFF80B7EC8D8B520CD11B988B5825D669AD05FE\"]/Displayed},{d32e0ab9-ea60-4e1e-bb38-bb8426664e7b;STRING;//Response[@Guid=\"9EFF80B7EC8D8B520CD11B988B5825D669AD05FE\"]/PDFVisible},{776f80bb-0293-4d20-8ecd-7597df5e818f;STRING;//Form/HideConditionalScreen},{783c57a7-1d71-424a-b60b-516a7515993c;STRING;//Response[@Guid=\"92AD1EF6A6FEE5D6D5B7CE04B60AD6B2369B1801\"]/Value},{1549cba6-84da-40c7-9f8e-eceb2c044dd7;STRING;//Response[@Guid=\"92AD1EF6A6FEE5D6D5B7CE04B60AD6B2369B1801\"]/Displayed},{584d343d-8a33-4d9a-b069-0e2c1e4d6a2f;STRING;//Response[@Guid=\"92AD1EF6A6FEE5D6D5B7CE04B60AD6B2369B1801\"]/PDFVisible},{e261f86d-76e4-4e29-a8bd-32fd3d1282b3;STRING;//Form/HideConditionalScreen},{c9087be2-4986-4e06-9c35-1b0b97b91b9a;STRING;//Form/HideConditionalScreen},{db68f9d2-123b-4230-b520-8b68405b6e80;STRING;//Response[@Guid=\"B5DF14C193EFAB631401CFE78CC0A15228764B23\"]/Value},{1c936da0-f467-4d43-baa1-6f1662d1fc93;STRING;//Response[@Guid=\"B5DF14C193EFAB631401CFE78CC0A15228764B23\"]/Displayed},{d7bfd25b-f103-4c5e-a98f-1c73c26bf545;STRING;//Response[@Guid=\"B5DF14C193EFAB631401CFE78CC0A15228764B23\"]/PDFVisible},{177f6163-aecc-47a7-9078-97e92c0208b3;STRING;//Response[@Guid=\"E99091AB355574C4A8030BC97C68B81E6EB3F735\"]/Value},{f9fd7cb9-0897-4f6a-9931-97e9295113e7;STRING;//Response[@Guid=\"E99091AB355574C4A8030BC97C68B81E6EB3F735\"]/Displayed},{62df09de-1e60-4c91-a1dd-05a9ccb7a77d;STRING;//Response[@Guid=\"E99091AB355574C4A8030BC97C68B81E6EB3F735\"]/PDFVisible},{5d51abbb-7730-4f69-8ad3-8800f266d125;STRING;//Response[@Guid=\"C4F2C0B1847C5A76BC751E8D1E62488F09A4E7BB\"]/Value},{60afd61b-cebd-4865-b921-c086052340aa;STRING;//Response[@Guid=\"C4F2C0B1847C5A76BC751E8D1E62488F09A4E7BB\"]/Displayed},{efa95347-6369-4766-b0d0-e0d5a908f498;STRING;//Response[@Guid=\"C4F2C0B1847C5A76BC751E8D1E62488F09A4E7BB\"]/PDFVisible},{774fa8b7-4a5b-4731-b3be-8ce3e868a88e;STRING;//Response[@Guid=\"ACFE9A0880B9A9F23F584F837898B23746F9CB75\"]/Value},{4c6a3bed-da52-4ff2-a1e6-ebc731aff3cf;STRING;//Response[@Guid=\"ACFE9A0880B9A9F23F584F837898B23746F9CB75\"]/Displayed},{ffc2811f-dd15-4548-8994-81b161b6fb1e;STRING;//Response[@Guid=\"ACFE9A0880B9A9F23F584F837898B23746F9CB75\"]/PDFVisible}]]></xml-property>\n        </oda-data-set>\n    </data-sets>\n    <styles>\n        <style name=\"crosstab\" id=\"2\">\n            <property name=\"borderBottomColor\">#CCCCCC</property>\n            <property name=\"borderBottomStyle\">solid</property>\n            <property name=\"borderBottomWidth\">1pt</property>\n            <property name=\"borderLeftColor\">#CCCCCC</property>\n            <property name=\"borderLeftStyle\">solid</property>\n            <property name=\"borderLeftWidth\">1pt</property>\n            <property name=\"borderRightColor\">#CCCCCC</property>\n            <property name=\"borderRightStyle\">solid</property>\n            <property name=\"borderRightWidth\">1pt</property>\n            <property name=\"borderTopColor\">#CCCCCC</property>\n            <property name=\"borderTopStyle\">solid</property>\n            <property name=\"borderTopWidth\">1pt</property>\n        </style>\n        <style name=\"crosstab-cell\" id=\"3\">\n            <property name=\"borderBottomColor\">#CCCCCC</property>\n            <property name=\"borderBottomStyle\">solid</property>\n            <property name=\"borderBottomWidth\">1pt</property>\n            <property name=\"borderLeftColor\">#CCCCCC</property>\n            <property name=\"borderLeftStyle\">solid</property>\n            <property name=\"borderLeftWidth\">1pt</property>\n            <property name=\"borderRightColor\">#CCCCCC</property>\n            <property name=\"borderRightStyle\">solid</property>\n            <property name=\"borderRightWidth\">1pt</property>\n            <property name=\"borderTopColor\">#CCCCCC</property>\n            <property name=\"borderTopStyle\">solid</property>\n            <property name=\"borderTopWidth\">1pt</property>\n        </style>\n        <style name=\"report\" id=\"6\">\n            <property name=\"fontFamily\">\"Helvetica\"</property>\n            <property name=\"fontSize\">15.600000000000001px</property>\n            <property name=\"fontWeight\">normal</property>\n            <property name=\"color\">#414042</property>\n        </style>\n        <style name=\"style9\" id=\"16\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">8px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">8px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">25.522%</property>\n        </style>\n        <style name=\"style10\" id=\"18\">\n            <property name=\"paddingTop\">28px</property>\n            <property name=\"paddingLeft\">8px</property>\n            <property name=\"paddingBottom\">14px</property>\n            <property name=\"paddingRight\">8px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">57.357%</property>\n        </style>\n        <style name=\"style11\" id=\"20\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">8px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">8px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">17.121%</property>\n        </style>\n        <style name=\"style28\" id=\"35\">\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">40%</property>\n        </style>\n        <style name=\"style29\" id=\"37\">\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">20%</property>\n        </style>\n        <style name=\"style30\" id=\"39\">\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">40%</property>\n        </style>\n        <style name=\"style42\" id=\"45\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">6px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">6px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">100%</property>\n        </style>\n        <style name=\"style48\" id=\"53\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">6px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">0px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">50%</property>\n        </style>\n        <style name=\"style49\" id=\"58\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">0px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">6px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">50%</property>\n        </style>\n        <style name=\"style64\" id=\"67\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">6px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">6px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">100%</property>\n        </style>\n        <style name=\"style71\" id=\"74\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">6px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">6px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">100%</property>\n        </style>\n        <style name=\"style77\" id=\"82\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">6px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">0px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">50%</property>\n        </style>\n        <style name=\"style78\" id=\"87\">\n            <property name=\"paddingTop\">8px</property>\n            <property name=\"paddingLeft\">0px</property>\n            <property name=\"paddingBottom\">8px</property>\n            <property name=\"paddingRight\">6px</property>\n            <property name=\"verticalAlign\">top</property>\n            <property name=\"width\">50%</property>\n        </style>\n    </styles>\n    <page-setup>\n        <simple-master-page name=\"75e0e90b-520a-424c-aa71-7658b22fc4e8\" id=\"7\">\n            <property name=\"type\">us-letter</property>\n            <property name=\"orientation\">portrait</property>\n            <property name=\"fontFamily\">\"Helvetica\"</property>\n            <property name=\"fontSize\">15.600000000000001px</property>\n            <property name=\"color\">#414042</property>\n            <property name=\"marginTop\">2%</property>\n            <property name=\"marginLeft\">2%</property>\n            <property name=\"marginBottom\">2%</property>\n            <property name=\"marginRight\">2%</property>\n            <property name=\"lineHeight\">143%</property>\n            <property name=\"headerHeight\">1in</property>\n            <property name=\"footerHeight\">25px</property>\n            <page-header>\n                <grid id=\"8\">\n                    <property name=\"marginBottom\">1px</property>\n                    <property name=\"width\">100%</property>\n                    <property name=\"dataSet\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n                    <list-property name=\"boundDataColumns\">\n                        <structure>\n                            <property name=\"name\">16d4ee9f-b632-45d6-989b-79e8c54b4e36</property>\n                            <expression name=\"expression\">dataSetRow[\"16d4ee9f-b632-45d6-989b-79e8c54b4e36\"]</expression>\n                        </structure>\n                        <structure>\n                            <property name=\"name\">bc966d19-d769-445f-b182-2305410553a4</property>\n                            <expression name=\"expression\">dataSetRow[\"bc966d19-d769-445f-b182-2305410553a4\"]</expression>\n                        </structure>\n                        <structure>\n                            <property name=\"name\">900ead6b-06d2-4e15-898e-5384983c454b</property>\n                            <expression name=\"expression\">dataSetRow[\"900ead6b-06d2-4e15-898e-5384983c454b\"]</expression>\n                        </structure>\n                        <structure>\n                            <property name=\"name\">2d5647b7-c166-4ec8-8e41-4fb8b43f8fad</property>\n                            <expression name=\"expression\">dataSetRow[\"2d5647b7-c166-4ec8-8e41-4fb8b43f8fad\"]</expression>\n                        </structure>\n                    </list-property>\n                    <column id=\"9\">\n                        <property name=\"style\">style9</property>\n                    </column>\n                    <column id=\"10\">\n                        <property name=\"style\">style10</property>\n                    </column>\n                    <column id=\"11\">\n                        <property name=\"style\">style11</property>\n                    </column>\n                    <row id=\"12\">\n                        <cell id=\"13\">\n                            <image name=\"c4215600-55e4-427f-8da0-1ce4610f3680\" id=\"17\">\n                                <property name=\"fontSize\">18.2px</property>\n                                <property name=\"color\">#000000</property>\n                                <property name=\"paddingTop\">1px</property>\n                                <property name=\"paddingBottom\">1px</property>\n                                <property name=\"width\">100%</property>\n                                <list-property name=\"visibility\">\n                                    <structure>\n                                        <property name=\"format\">all</property>\n                                        <expression name=\"valueExpr\">\"https://demo.gocanvas.com/pdf_builder_images/41935820dc1c8516462f898adbfbcae5dcc6\" == \"null\"</expression>\n                                    </structure>\n                                </list-property>\n                                <property name=\"source\">url</property>\n                                <property name=\"fitToContainer\">true</property>\n                                <property name=\"proportionalScale\">true</property>\n                                <expression name=\"uri\">\"https://demo.gocanvas.com/pdf_builder_images/41935820dc1c8516462f898adbfbcae5dcc6\"</expression>\n                                <expression name=\"altText\" type=\"javascript\">if(true) \"\"</expression>\n                            </image>\n                        </cell>\n                        <cell id=\"14\">\n                            <text name=\"b7d24a1d-607e-43a4-9e95-0cd2430b86c9\" id=\"19\">\n                                <property name=\"fontSize\">20.8px</property>\n                                <property name=\"fontWeight\">bold</property>\n                                <property name=\"color\">#414042</property>\n                                <property name=\"paddingTop\">1px</property>\n                                <property name=\"paddingBottom\">1px</property>\n                                <property name=\"textAlign\">center</property>\n                                <property name=\"lineHeight\">143%</property>\n                                <property name=\"contentType\">html</property>\n                                <text-property name=\"content\"><![CDATA[Your Business Name]]></text-property>\n                            </text>\n                        </cell>\n                        <cell id=\"15\">\n                            <label id=\"21\">\n                                <property name=\"fontSize\">12px</property>\n                                <property name=\"fontWeight\">bold</property>\n                                <property name=\"color\">#414042</property>\n                                <property name=\"paddingTop\">10px</property>\n                                <property name=\"paddingBottom\">10px</property>\n                                <property name=\"textAlign\">left</property>\n                                <property name=\"lineHeight\">143%</property>\n                                <list-property name=\"visibility\">\n                                    <structure>\n                                        <property name=\"format\">all</property>\n                                        <expression name=\"valueExpr\">row[\"2d5647b7-c166-4ec8-8e41-4fb8b43f8fad\"] == \"false\" || (row[\"16d4ee9f-b632-45d6-989b-79e8c54b4e36\"] == \"true\" &amp;&amp; row[\"900ead6b-06d2-4e15-898e-5384983c454b\"] == \"false\")</expression>\n                                    </structure>\n                                </list-property>\n                                <text-property name=\"text\">Date</text-property>\n                            </label>\n                            <data name=\"33112a84-438e-4bd9-a392-af7335a358c4\" id=\"22\">\n                                <property name=\"fontSize\">15.600000000000001px</property>\n                                <property name=\"fontWeight\">normal</property>\n                                <property name=\"color\">#414042</property>\n                                <property name=\"paddingBottom\">10px</property>\n                                <property name=\"textAlign\">left</property>\n                                <property name=\"lineHeight\">143%</property>\n                                <list-property name=\"visibility\">\n                                    <structure>\n                                        <property name=\"format\">all</property>\n                                        <expression name=\"valueExpr\">row[\"2d5647b7-c166-4ec8-8e41-4fb8b43f8fad\"] == \"false\" || (row[\"16d4ee9f-b632-45d6-989b-79e8c54b4e36\"] == \"true\" &amp;&amp; row[\"900ead6b-06d2-4e15-898e-5384983c454b\"] == \"false\")</expression>\n                                    </structure>\n                                </list-property>\n                                <property name=\"resultSetColumn\">bc966d19-d769-445f-b182-2305410553a4</property>\n                            </data>\n                        </cell>\n                    </row>\n                </grid>\n            </page-header>\n            <page-footer>\n                <grid id=\"23\">\n                    <property name=\"width\">100%</property>\n                    <property name=\"dataSet\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n                    <column id=\"24\"/>\n                    <row id=\"25\">\n                        <cell id=\"26\">\n                            <grid name=\"sectionGrid\" id=\"27\">\n                                <property name=\"marginTop\">5px</property>\n                                <property name=\"width\">100%</property>\n                                <property name=\"dataSet\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n                                <list-property name=\"boundDataColumns\">\n                                    <structure>\n                                        <property name=\"name\">6d0ab69f-16fd-4aca-b2e1-b35938d794ba</property>\n                                        <expression name=\"expression\">dataSetRow[\"6d0ab69f-16fd-4aca-b2e1-b35938d794ba\"]</expression>\n                                    </structure>\n                                    <structure>\n                                        <property name=\"name\">b6601e1a-25cd-4a06-a920-c2993757ca8a</property>\n                                        <expression name=\"expression\">dataSetRow[\"b6601e1a-25cd-4a06-a920-c2993757ca8a\"]</expression>\n                                    </structure>\n                                </list-property>\n                                <column id=\"28\">\n                                    <property name=\"style\">style28</property>\n                                </column>\n                                <column id=\"29\">\n                                    <property name=\"style\">style29</property>\n                                </column>\n                                <column id=\"30\">\n                                    <property name=\"style\">style30</property>\n                                </column>\n                                <row id=\"31\">\n                                    <cell id=\"32\">\n                                        <image name=\"660ef121-f756-4076-aa6f-7468cdcbf048\" id=\"36\">\n                                            <property name=\"marginLeft\">-15px</property>\n                                            <property name=\"height\">20px</property>\n                                            <property name=\"width\">120px</property>\n                                            <list-property name=\"visibility\">\n                                                <structure>\n                                                    <property name=\"format\">all</property>\n                                                    <expression name=\"valueExpr\">\"https://demo.gocanvas.com/images/pdfbuilder/powered_by_canvas.png\" == \"null\"</expression>\n                                                </structure>\n                                            </list-property>\n                                            <property name=\"source\">url</property>\n                                            <property name=\"fitToContainer\">true</property>\n                                            <property name=\"proportionalScale\">true</property>\n                                            <expression name=\"uri\">\"https://demo.gocanvas.com/images/pdfbuilder/powered_by_canvas.png\"</expression>\n                                            <expression name=\"altText\" type=\"javascript\">if(true) \"\"</expression>\n                                            <list-property name=\"action\">\n                                                <structure>\n                                                    <property name=\"linkType\">hyperlink</property>\n                                                    <expression name=\"uri\" type=\"constant\">http://www.gocanvas.com/?utm_source=canvas_pdf&amp;utm_medium=pdf_link&amp;utm_campaign=canvas_pdf_link</expression>\n                                                </structure>\n                                            </list-property>\n                                        </image>\n                                    </cell>\n                                    <cell id=\"33\">\n                                        <label id=\"38\">\n                                            <property name=\"fontSize\">12px</property>\n                                            <property name=\"color\">#27AAE1</property>\n                                            <property name=\"textAlign\">center</property>\n                                            <property name=\"lineHeight\">100%</property>\n                                            <text-property name=\"text\">www.gocanvas.com</text-property>\n                                            <list-property name=\"action\">\n                                                <structure>\n                                                    <property name=\"linkType\">hyperlink</property>\n                                                    <expression name=\"uri\" type=\"constant\">http://www.gocanvas.com/?utm_source=canvas_pdf&amp;utm_medium=pdf_link&amp;utm_campaign=canvas_pdf_link</expression>\n                                                </structure>\n                                            </list-property>\n                                        </label>\n                                    </cell>\n                                    <cell id=\"34\">\n                                        <data name=\"450d25ca-3851-4347-98d3-73693be9775a\" id=\"40\">\n                                            <property name=\"fontSize\">12px</property>\n                                            <property name=\"color\">#ADB0B3</property>\n                                            <property name=\"textAlign\">right</property>\n                                            <property name=\"lineHeight\">100%</property>\n                                            <property name=\"resultSetColumn\">b6601e1a-25cd-4a06-a920-c2993757ca8a</property>\n                                        </data>\n                                    </cell>\n                                </row>\n                            </grid>\n                        </cell>\n                    </row>\n                </grid>\n            </page-footer>\n        </simple-master-page>\n    </page-setup>\n    <body>\n        <grid id=\"41\">\n            <property name=\"marginBottom\">1px</property>\n            <property name=\"width\">100%</property>\n            <property name=\"dataSet\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n            <list-property name=\"boundDataColumns\">\n                <structure>\n                    <property name=\"name\">0c55f802-e5a3-4b49-970d-679e21920c56</property>\n                    <expression name=\"expression\">dataSetRow[\"0c55f802-e5a3-4b49-970d-679e21920c56\"]</expression>\n                </structure>\n            </list-property>\n            <column id=\"42\">\n                <property name=\"style\">style42</property>\n            </column>\n            <row id=\"43\">\n                <cell id=\"44\">\n                    <text name=\"8cc8557c-9291-4912-9ce3-3a5e188a7766\" id=\"46\">\n                        <property name=\"backgroundColor\">#00305E</property>\n                        <property name=\"fontSize\">18.2px</property>\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"color\">#FFFFFF</property>\n                        <property name=\"borderBottomColor\">#00305E</property>\n                        <property name=\"borderBottomStyle\">solid</property>\n                        <property name=\"borderBottomWidth\">1px</property>\n                        <property name=\"borderLeftColor\">#00305E</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#00305E</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"borderTopColor\">#00305E</property>\n                        <property name=\"borderTopStyle\">solid</property>\n                        <property name=\"borderTopWidth\">1px</property>\n                        <property name=\"paddingTop\">3px</property>\n                        <property name=\"paddingBottom\">3px</property>\n                        <property name=\"textAlign\">center</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <property name=\"contentType\">html</property>\n                        <text-property name=\"content\"><![CDATA[General Information]]></text-property>\n                    </text>\n                </cell>\n            </row>\n        </grid>\n        <grid id=\"47\">\n            <property name=\"marginBottom\">1px</property>\n            <property name=\"width\">100%</property>\n            <property name=\"dataSet\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n            <list-property name=\"boundDataColumns\">\n                <structure>\n                    <property name=\"name\">3089bd7c-0287-4d56-86b1-e21a52e34e6c</property>\n                    <expression name=\"expression\">dataSetRow[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">652bb715-39fd-4c9f-b328-1c4650ae5c90</property>\n                    <expression name=\"expression\">dataSetRow[\"652bb715-39fd-4c9f-b328-1c4650ae5c90\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">12a83f67-6234-494b-ad66-82f7d515afcb</property>\n                    <expression name=\"expression\">dataSetRow[\"12a83f67-6234-494b-ad66-82f7d515afcb\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">7e6a9d44-3791-49d1-8ab2-0aaec42b1394</property>\n                    <expression name=\"expression\">dataSetRow[\"7e6a9d44-3791-49d1-8ab2-0aaec42b1394\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">18a0b3d2-f9fa-4fde-97f3-f50d3a013c99</property>\n                    <expression name=\"expression\">dataSetRow[\"18a0b3d2-f9fa-4fde-97f3-f50d3a013c99\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">62cf2d6a-b714-41ee-97be-5a6153430d3b</property>\n                    <expression name=\"expression\">dataSetRow[\"62cf2d6a-b714-41ee-97be-5a6153430d3b\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">4a6abda6-d3f7-4431-afec-939d270d0967</property>\n                    <expression name=\"expression\">dataSetRow[\"4a6abda6-d3f7-4431-afec-939d270d0967\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">1e90160e-f503-4d84-999b-a36540841a8c</property>\n                    <expression name=\"expression\">dataSetRow[\"1e90160e-f503-4d84-999b-a36540841a8c\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">52ab588a-d9d3-4613-b22f-6c989a9b3bed</property>\n                    <expression name=\"expression\">dataSetRow[\"52ab588a-d9d3-4613-b22f-6c989a9b3bed\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">f40ff177-4d8e-4707-8fa1-1ecccd44671f</property>\n                    <expression name=\"expression\">dataSetRow[\"f40ff177-4d8e-4707-8fa1-1ecccd44671f\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">91961290-f362-452d-b90d-8966733e7d3c</property>\n                    <expression name=\"expression\">dataSetRow[\"91961290-f362-452d-b90d-8966733e7d3c\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">e9a3b434-9ba4-464e-ade7-a68272b34372</property>\n                    <expression name=\"expression\">dataSetRow[\"e9a3b434-9ba4-464e-ade7-a68272b34372\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">d32e0ab9-ea60-4e1e-bb38-bb8426664e7b</property>\n                    <expression name=\"expression\">dataSetRow[\"d32e0ab9-ea60-4e1e-bb38-bb8426664e7b\"]</expression>\n                </structure>\n            </list-property>\n            <column id=\"48\">\n                <property name=\"style\">style48</property>\n            </column>\n            <column id=\"49\">\n                <property name=\"style\">style49</property>\n            </column>\n            <row id=\"50\">\n                <cell id=\"51\">\n                    <label id=\"54\">\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"7e6a9d44-3791-49d1-8ab2-0aaec42b1394\"] == \"false\" || (row[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"] == \"true\" &amp;&amp; row[\"12a83f67-6234-494b-ad66-82f7d515afcb\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">Employee Name</text-property>\n                    </label>\n                    <data name=\"6f96de37-d472-45f7-880a-a9d1e9a336d6\" id=\"55\">\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"7e6a9d44-3791-49d1-8ab2-0aaec42b1394\"] == \"false\" || (row[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"] == \"true\" &amp;&amp; row[\"12a83f67-6234-494b-ad66-82f7d515afcb\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">652bb715-39fd-4c9f-b328-1c4650ae5c90</property>\n                    </data>\n                    <label id=\"56\">\n                        <property name=\"backgroundColor\">#FBFCFD</property>\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"borderLeftColor\">#FBFCFD</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#FBFCFD</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"borderTopColor\">#FBFCFD</property>\n                        <property name=\"borderTopStyle\">solid</property>\n                        <property name=\"borderTopWidth\">1px</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"4a6abda6-d3f7-4431-afec-939d270d0967\"] == \"false\" || (row[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"] == \"true\" &amp;&amp; row[\"62cf2d6a-b714-41ee-97be-5a6153430d3b\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">Employee ID</text-property>\n                    </label>\n                    <data name=\"94da1549-3dd9-4c84-844a-e55dc13a60ca\" id=\"57\">\n                        <property name=\"backgroundColor\">#FBFCFD</property>\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"borderBottomColor\">#FBFCFD</property>\n                        <property name=\"borderBottomStyle\">solid</property>\n                        <property name=\"borderBottomWidth\">1px</property>\n                        <property name=\"borderLeftColor\">#FBFCFD</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#FBFCFD</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"4a6abda6-d3f7-4431-afec-939d270d0967\"] == \"false\" || (row[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"] == \"true\" &amp;&amp; row[\"62cf2d6a-b714-41ee-97be-5a6153430d3b\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">18a0b3d2-f9fa-4fde-97f3-f50d3a013c99</property>\n                    </data>\n                </cell>\n                <cell id=\"52\">\n                    <label id=\"59\">\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"f40ff177-4d8e-4707-8fa1-1ecccd44671f\"] == \"false\" || (row[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"] == \"true\" &amp;&amp; row[\"52ab588a-d9d3-4613-b22f-6c989a9b3bed\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">Start Time</text-property>\n                    </label>\n                    <data name=\"77a55a2c-cbd3-4832-b033-6fac227d90c7\" id=\"60\">\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"f40ff177-4d8e-4707-8fa1-1ecccd44671f\"] == \"false\" || (row[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"] == \"true\" &amp;&amp; row[\"52ab588a-d9d3-4613-b22f-6c989a9b3bed\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">1e90160e-f503-4d84-999b-a36540841a8c</property>\n                    </data>\n                    <label id=\"61\">\n                        <property name=\"backgroundColor\">#FBFCFD</property>\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"borderLeftColor\">#FBFCFD</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#FBFCFD</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"borderTopColor\">#FBFCFD</property>\n                        <property name=\"borderTopStyle\">solid</property>\n                        <property name=\"borderTopWidth\">1px</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"d32e0ab9-ea60-4e1e-bb38-bb8426664e7b\"] == \"false\" || (row[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"] == \"true\" &amp;&amp; row[\"e9a3b434-9ba4-464e-ade7-a68272b34372\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">End Time</text-property>\n                    </label>\n                    <data name=\"df872395-5845-44b1-88fe-f497639ce3b4\" id=\"62\">\n                        <property name=\"backgroundColor\">#FBFCFD</property>\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"borderBottomColor\">#FBFCFD</property>\n                        <property name=\"borderBottomStyle\">solid</property>\n                        <property name=\"borderBottomWidth\">1px</property>\n                        <property name=\"borderLeftColor\">#FBFCFD</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#FBFCFD</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"d32e0ab9-ea60-4e1e-bb38-bb8426664e7b\"] == \"false\" || (row[\"3089bd7c-0287-4d56-86b1-e21a52e34e6c\"] == \"true\" &amp;&amp; row[\"e9a3b434-9ba4-464e-ade7-a68272b34372\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">91961290-f362-452d-b90d-8966733e7d3c</property>\n                    </data>\n                </cell>\n            </row>\n        </grid>\n        <grid id=\"63\">\n            <property name=\"marginBottom\">1px</property>\n            <property name=\"width\">100%</property>\n            <property name=\"dataSet\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n            <list-property name=\"boundDataColumns\">\n                <structure>\n                    <property name=\"name\">776f80bb-0293-4d20-8ecd-7597df5e818f</property>\n                    <expression name=\"expression\">dataSetRow[\"776f80bb-0293-4d20-8ecd-7597df5e818f\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">783c57a7-1d71-424a-b60b-516a7515993c</property>\n                    <expression name=\"expression\">dataSetRow[\"783c57a7-1d71-424a-b60b-516a7515993c\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">1549cba6-84da-40c7-9f8e-eceb2c044dd7</property>\n                    <expression name=\"expression\">dataSetRow[\"1549cba6-84da-40c7-9f8e-eceb2c044dd7\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">584d343d-8a33-4d9a-b069-0e2c1e4d6a2f</property>\n                    <expression name=\"expression\">dataSetRow[\"584d343d-8a33-4d9a-b069-0e2c1e4d6a2f\"]</expression>\n                </structure>\n            </list-property>\n            <column id=\"64\">\n                <property name=\"style\">style64</property>\n            </column>\n            <row id=\"65\">\n                <list-property name=\"visibility\">\n                    <structure>\n                        <property name=\"format\">all</property>\n                        <expression name=\"valueExpr\">row[\"584d343d-8a33-4d9a-b069-0e2c1e4d6a2f\"] == \"false\" || (row[\"776f80bb-0293-4d20-8ecd-7597df5e818f\"] == \"true\" &amp;&amp; row[\"1549cba6-84da-40c7-9f8e-eceb2c044dd7\"] == \"false\")</expression>\n                    </structure>\n                </list-property>\n                <cell id=\"66\">\n                    <label id=\"68\">\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"584d343d-8a33-4d9a-b069-0e2c1e4d6a2f\"] == \"false\" || (row[\"776f80bb-0293-4d20-8ecd-7597df5e818f\"] == \"true\" &amp;&amp; row[\"1549cba6-84da-40c7-9f8e-eceb2c044dd7\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">Work Performed</text-property>\n                    </label>\n                    <data name=\"d2993f6e-42c1-423d-ae67-4c0c7f01c214\" id=\"69\">\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"584d343d-8a33-4d9a-b069-0e2c1e4d6a2f\"] == \"false\" || (row[\"776f80bb-0293-4d20-8ecd-7597df5e818f\"] == \"true\" &amp;&amp; row[\"1549cba6-84da-40c7-9f8e-eceb2c044dd7\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">783c57a7-1d71-424a-b60b-516a7515993c</property>\n                    </data>\n                </cell>\n            </row>\n        </grid>\n        <grid id=\"70\">\n            <property name=\"marginBottom\">1px</property>\n            <property name=\"width\">100%</property>\n            <property name=\"dataSet\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n            <list-property name=\"boundDataColumns\">\n                <structure>\n                    <property name=\"name\">e261f86d-76e4-4e29-a8bd-32fd3d1282b3</property>\n                    <expression name=\"expression\">dataSetRow[\"e261f86d-76e4-4e29-a8bd-32fd3d1282b3\"]</expression>\n                </structure>\n            </list-property>\n            <column id=\"71\">\n                <property name=\"style\">style71</property>\n            </column>\n            <row id=\"72\">\n                <cell id=\"73\">\n                    <text name=\"6e86b1fc-8b84-4da0-9abf-a91f3c24d242\" id=\"75\">\n                        <property name=\"backgroundColor\">#00305E</property>\n                        <property name=\"fontSize\">18.2px</property>\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"fontStyle\">normal</property>\n                        <property name=\"color\">#FFFFFF</property>\n                        <property name=\"textUnderline\">none</property>\n                        <property name=\"borderBottomColor\">#00305E</property>\n                        <property name=\"borderBottomStyle\">solid</property>\n                        <property name=\"borderBottomWidth\">1px</property>\n                        <property name=\"borderLeftColor\">#00305E</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#00305E</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"borderTopColor\">#00305E</property>\n                        <property name=\"borderTopStyle\">solid</property>\n                        <property name=\"borderTopWidth\">1px</property>\n                        <property name=\"paddingTop\">3px</property>\n                        <property name=\"paddingBottom\">3px</property>\n                        <property name=\"textAlign\">center</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <property name=\"contentType\">html</property>\n                        <text-property name=\"content\"><![CDATA[Summary]]></text-property>\n                    </text>\n                </cell>\n            </row>\n        </grid>\n        <grid id=\"76\">\n            <property name=\"marginBottom\">1px</property>\n            <property name=\"width\">100%</property>\n            <property name=\"dataSet\">75e0e90b-520a-424c-aa71-7658b22fc4e8</property>\n            <list-property name=\"boundDataColumns\">\n                <structure>\n                    <property name=\"name\">c9087be2-4986-4e06-9c35-1b0b97b91b9a</property>\n                    <expression name=\"expression\">dataSetRow[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">db68f9d2-123b-4230-b520-8b68405b6e80</property>\n                    <expression name=\"expression\">dataSetRow[\"db68f9d2-123b-4230-b520-8b68405b6e80\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">1c936da0-f467-4d43-baa1-6f1662d1fc93</property>\n                    <expression name=\"expression\">dataSetRow[\"1c936da0-f467-4d43-baa1-6f1662d1fc93\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">d7bfd25b-f103-4c5e-a98f-1c73c26bf545</property>\n                    <expression name=\"expression\">dataSetRow[\"d7bfd25b-f103-4c5e-a98f-1c73c26bf545\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">177f6163-aecc-47a7-9078-97e92c0208b3</property>\n                    <expression name=\"expression\">dataSetRow[\"177f6163-aecc-47a7-9078-97e92c0208b3\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">f9fd7cb9-0897-4f6a-9931-97e9295113e7</property>\n                    <expression name=\"expression\">dataSetRow[\"f9fd7cb9-0897-4f6a-9931-97e9295113e7\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">62df09de-1e60-4c91-a1dd-05a9ccb7a77d</property>\n                    <expression name=\"expression\">dataSetRow[\"62df09de-1e60-4c91-a1dd-05a9ccb7a77d\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">5d51abbb-7730-4f69-8ad3-8800f266d125</property>\n                    <expression name=\"expression\">dataSetRow[\"5d51abbb-7730-4f69-8ad3-8800f266d125\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">60afd61b-cebd-4865-b921-c086052340aa</property>\n                    <expression name=\"expression\">dataSetRow[\"60afd61b-cebd-4865-b921-c086052340aa\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">efa95347-6369-4766-b0d0-e0d5a908f498</property>\n                    <expression name=\"expression\">dataSetRow[\"efa95347-6369-4766-b0d0-e0d5a908f498\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">774fa8b7-4a5b-4731-b3be-8ce3e868a88e</property>\n                    <expression name=\"expression\">dataSetRow[\"774fa8b7-4a5b-4731-b3be-8ce3e868a88e\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">4c6a3bed-da52-4ff2-a1e6-ebc731aff3cf</property>\n                    <expression name=\"expression\">dataSetRow[\"4c6a3bed-da52-4ff2-a1e6-ebc731aff3cf\"]</expression>\n                </structure>\n                <structure>\n                    <property name=\"name\">ffc2811f-dd15-4548-8994-81b161b6fb1e</property>\n                    <expression name=\"expression\">dataSetRow[\"ffc2811f-dd15-4548-8994-81b161b6fb1e\"]</expression>\n                </structure>\n            </list-property>\n            <column id=\"77\">\n                <property name=\"style\">style77</property>\n            </column>\n            <column id=\"78\">\n                <property name=\"style\">style78</property>\n            </column>\n            <row id=\"79\">\n                <cell id=\"80\">\n                    <label id=\"83\">\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"d7bfd25b-f103-4c5e-a98f-1c73c26bf545\"] == \"false\" || (row[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"] == \"true\" &amp;&amp; row[\"1c936da0-f467-4d43-baa1-6f1662d1fc93\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">Hours Worked</text-property>\n                    </label>\n                    <data name=\"8e65bfdd-ae00-4e53-a0f2-ca53202a35bc\" id=\"84\">\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"d7bfd25b-f103-4c5e-a98f-1c73c26bf545\"] == \"false\" || (row[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"] == \"true\" &amp;&amp; row[\"1c936da0-f467-4d43-baa1-6f1662d1fc93\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">db68f9d2-123b-4230-b520-8b68405b6e80</property>\n                    </data>\n                    <label id=\"85\">\n                        <property name=\"backgroundColor\">#FBFCFD</property>\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"borderLeftColor\">#FBFCFD</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#FBFCFD</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"borderTopColor\">#FBFCFD</property>\n                        <property name=\"borderTopStyle\">solid</property>\n                        <property name=\"borderTopWidth\">1px</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"62df09de-1e60-4c91-a1dd-05a9ccb7a77d\"] == \"false\" || (row[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"] == \"true\" &amp;&amp; row[\"f9fd7cb9-0897-4f6a-9931-97e9295113e7\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">Overtime Approval Required?</text-property>\n                    </label>\n                    <data name=\"94678a87-0c76-4682-af1f-927fa499f9be\" id=\"86\">\n                        <property name=\"backgroundColor\">#FBFCFD</property>\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"fontStyle\">normal</property>\n                        <property name=\"textUnderline\">none</property>\n                        <property name=\"borderBottomColor\">#FBFCFD</property>\n                        <property name=\"borderBottomStyle\">solid</property>\n                        <property name=\"borderBottomWidth\">1px</property>\n                        <property name=\"borderLeftColor\">#FBFCFD</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#FBFCFD</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"62df09de-1e60-4c91-a1dd-05a9ccb7a77d\"] == \"false\" || (row[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"] == \"true\" &amp;&amp; row[\"f9fd7cb9-0897-4f6a-9931-97e9295113e7\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">177f6163-aecc-47a7-9078-97e92c0208b3</property>\n                    </data>\n                </cell>\n                <cell id=\"81\">\n                    <label id=\"88\">\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"efa95347-6369-4766-b0d0-e0d5a908f498\"] == \"false\" || (row[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"] == \"true\" &amp;&amp; row[\"60afd61b-cebd-4865-b921-c086052340aa\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">Regular Hours</text-property>\n                    </label>\n                    <data name=\"5a257a9b-82bb-4674-b307-7953f5d7181b\" id=\"89\">\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"efa95347-6369-4766-b0d0-e0d5a908f498\"] == \"false\" || (row[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"] == \"true\" &amp;&amp; row[\"60afd61b-cebd-4865-b921-c086052340aa\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">5d51abbb-7730-4f69-8ad3-8800f266d125</property>\n                    </data>\n                    <label id=\"90\">\n                        <property name=\"backgroundColor\">#FBFCFD</property>\n                        <property name=\"fontSize\">12px</property>\n                        <property name=\"fontWeight\">bold</property>\n                        <property name=\"borderLeftColor\">#FBFCFD</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#FBFCFD</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"borderTopColor\">#FBFCFD</property>\n                        <property name=\"borderTopStyle\">solid</property>\n                        <property name=\"borderTopWidth\">1px</property>\n                        <property name=\"paddingTop\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"ffc2811f-dd15-4548-8994-81b161b6fb1e\"] == \"false\" || (row[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"] == \"true\" &amp;&amp; row[\"4c6a3bed-da52-4ff2-a1e6-ebc731aff3cf\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <text-property name=\"text\">Overtime Hours</text-property>\n                    </label>\n                    <data name=\"c96bd0fe-aeca-4fc4-87cd-eb197a210bca\" id=\"91\">\n                        <property name=\"backgroundColor\">#FBFCFD</property>\n                        <property name=\"fontWeight\">normal</property>\n                        <property name=\"fontStyle\">normal</property>\n                        <property name=\"textUnderline\">none</property>\n                        <property name=\"borderBottomColor\">#FBFCFD</property>\n                        <property name=\"borderBottomStyle\">solid</property>\n                        <property name=\"borderBottomWidth\">1px</property>\n                        <property name=\"borderLeftColor\">#FBFCFD</property>\n                        <property name=\"borderLeftStyle\">solid</property>\n                        <property name=\"borderLeftWidth\">1px</property>\n                        <property name=\"borderRightColor\">#FBFCFD</property>\n                        <property name=\"borderRightStyle\">solid</property>\n                        <property name=\"borderRightWidth\">1px</property>\n                        <property name=\"paddingBottom\">1px</property>\n                        <property name=\"textAlign\">left</property>\n                        <property name=\"lineHeight\">143%</property>\n                        <list-property name=\"visibility\">\n                            <structure>\n                                <property name=\"format\">all</property>\n                                <expression name=\"valueExpr\">row[\"ffc2811f-dd15-4548-8994-81b161b6fb1e\"] == \"false\" || (row[\"c9087be2-4986-4e06-9c35-1b0b97b91b9a\"] == \"true\" &amp;&amp; row[\"4c6a3bed-da52-4ff2-a1e6-ebc731aff3cf\"] == \"false\")</expression>\n                            </structure>\n                        </list-property>\n                        <property name=\"resultSetColumn\">774fa8b7-4a5b-4731-b3be-8ce3e868a88e</property>\n                    </data>\n                </cell>\n            </row>\n        </grid>\n    </body>\n</report>\n",
  "created_at": "2021-09-22 19:34:17 UTC",
  "updated_at": "2021-09-22 19:34:17 UTC",
  "format": "PDF",
  "default_emailed": true
}

Generate PDF with Report ID

To generate a specific Report from a Submission, use the List of Reports By Form API above to find the Report's ID, then use the Submission ID and Report ID together to request a PDF:

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  https://www.gocanvas.com/api/v3/submissions/52523/reports/32525 --output custom_pdf.pdf

require 'net/http'

username = "api.user@example.com"
password = "supersecretpassword"

endpoint = "https://www.gocanvas.com/api/v3/submissions/52523/reports/32525"

uri = URI.parse(endpoint)
req = Net::HTTP::Get.new(endpoint)
http = Net::HTTP.new(uri.host, uri.port)
http.read_timeout = 5
http.open_timeout = 5

req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
    http.request(req)
end

const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/submissions/52523/reports/32525", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password)
  },
})
  .then(response => response.blob())
  .then(report => console.log(report));

HTTP Request

GET https://www.gocanvas.com/api/v3/submissions/160504422/reports/8433

Request Parameters

Parameter Type Description
submission_id integer The unique identifier of a Submission
report_id integer The unique identifier of the Report
// response will be the pdf as a binary file

Locations

Use the Locations endpoint to retrieve the sequence of location events captured by Tracker. You can scope the results to a single mobile user or, by omitting the user_id, retrieve activity for every user in your company. Each event contains device metadata that helps you reconstruct where users were and what state the Tracker session was in.

The Location object

Example

{
  "id": 456789012,
  "user_id": 314159,
  "site_id": null,
  "event_type": "start_tracking",
  "recorded_at": "2025-09-17T14:22:39Z",
  "lat": 40.7128,
  "lon": -74.006,
  "gps_accuracy": 3.5,
  "speed": -1.0,
  "direction": 90.0,
  "battery": 42,
  "device_type": "android",
  "version": "2.0.0 (789)",
  "created_at": "2025-09-17T14:25:10Z",
  "address": "123 Market Street",
  "city": "Philadelphia",
  "state": "PA",
  "zip_code": "19107",
  "country": "US"
}

Each entry represents a single point captured by the mobile tracker. The structure below reflects the serialized payload returned by the API.

Attributes

Field Type Description
id integer Unique identifier of the location event.
user_id integer Identifier of the user associated with the event.
event_type enum Type of event. See Location Event Types for details.
site_id integer Identifier of the site associated with the event, if any.
recorded_at string Timestamp when the event was recorded on the device.
created_at string Timestamp when the event was saved to the database.
lat number Latitude in decimal degrees.
lon number Longitude in decimal degrees.
gps_accuracy number Horizontal accuracy in meters as reported by the device.
speed number Speed reported by the device in meters per second. A value of -1 indicates the device did not report speed.
direction number Bearing in degrees (0–360) reported by the device.
battery integer Device battery level percentage when the event was recorded.
device_type string Platform reported by the device (e.g. ios, android).
version string Mobile app version string reported by the device.
address* string Street address associated with the location event.
city* string City associated with the location event.
state* string State or province associated with the location event.
zip_code* string Postal code associated with the location event.
country* string Two-letter country code associated with the location event.

* For the location event type, the denoted fields are returned with empty string values.

Location Event Types

Value Description
location General location tracking event.
start_tracking User taps “Start Tracking” in the app.
stop_tracking User taps “Stop Tracking” in the app.
planned_stop User has arrived within roughly 100 meters of a site.
planned_stop_end Marks the end of a planned stop.
planned_stop_created A new submission is created on mobile for a site (address).
planned_stop_deleted A submission for a site is deleted from the device.
unplanned_stop User has been idle (not moved beyond the configured threshold) for more than five minutes.
unplanned_stop_end Marks the end of an unplanned stop.

List all Locations

Retrieve the location events captured for a user within a limited date range. e.g a specific time during the day

Retrieve the location events captured for a user spanning multiple days

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/tracker/locations?start_date=2025-09-17&end_date=2025-09-20
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/tracker/locations?start_date=2025-09-17&end_date=2025-09-20")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

tracker_locations_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/tracker/locations?start_date=2025-09-17&end_date=2025-09-20", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(tracker_locations => console.log(tracker_locations));

HTTP Request

GET https://www.gocanvas.com/api/v3/tracker/locations

Query Parameters

Parameter Type Description Default
user_id integer (optional) Optional. Limit results to a specific user in your company. Omit to retrieve events for all users in your company.
start_date* string Required. Beginning of the window to search. When only a date is provided, it is interpreted as 00:00:00 for that day.
end_date* string Required. End of the window to search. When only a date is provided, it is interpreted as 23:59:59 for that day.
page integer (optional) The page requested, see Pagination. 1
use_created_at boolean (optional) When true, filter and sort records using their created_at timestamp instead of recorded_at. Use this to pull all events that were uploaded during a window, even if they were recorded earlier. false

* start_date and end_date must be in the ISO-8601 format, e.g. 2024-01-30, 2024-01-30T00:00:00, or 2024-01-30T00:00:00-04:00.

Site

A site represents a physical location where work is conducted. To create a site, the user must have authorization to create a site for the associated company.

The Site object

EXAMPLE

{
  "id": 7,
  "type": "site",
  "name": "Site #1",
  "address": "1234 Elm Street",
  "city": "Springfield",
  "state": "IL",
  "zip_code": "62704",
  "country": "US",
  "code": "A1B2C3"
}

A Site requires a name to be created. The name is the only required field, and will be associated by default to the company of the User creating the site.

Customers and Sites

A Site can be associated with a single Customer. By passing a customer_id in the PATCH request for a site, you can assign the Site to the Customer. The Customer must be associated with the same company as the Site.

A Site can only be associated with one Customer. If the Customer doesn't have a Primary Site, the Site will be considered the Primary Site. If the Customer already has a Primary Site, the Site will be considered an Additional Site.

List all Sites

Users can view a list of all the Sites associated with their company.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/sites
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/sites")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

sites_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/sites", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(sites => console.log(sites));

RESPONSE

[
  {
    "id": 7,
    "type": "site",
    "name": "Site #1",
    "address": "1234 Elm Street",
    "city": "Springfield",
    "state": "IL",
    "zip_code": "62704",
    "country": "US",
    "code": "A1B2C3"
  },
  {
    "id": 8,
    "type": "site",
    "name": "Site #2",
    "address": "5678 Oak Avenue",
    "city": "Metropolis",
    "state": "NY",
    "zip_code": "10001",
    "country": "US",
    "code": "D4E5F6"
  },
  {
    "id": 9,
    "type": "site",
    "name": "Site #3",
    "address": "9101 Pine Lane",
    "city": "Gotham",
    "state": "NJ",
    "zip_code": "07001",
    "country": "US",
    "code": "G7H8I9"
  }
]

HTTP Request

GET https://www.gocanvas.com/api/v3/sites

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1

Retrieve a Site

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/sites/7
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/sites/7")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

site_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/sites/7", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(site => console.log(site));

Users can retrieve a Site by its ID.

HTTP Request

GET https://www.gocanvas.com/api/v3/sites/7

RESPONSE

{
  "id": 7,
  "type": "site",
  "name": "Site #1",
  "address": "1234 Elm Street",
  "city": "Springfield",
  "state": "IL",
  "zip_code": "62704",
  "country": "US",
  "code": "A1B2C3"
}

Response Parameters

Parameter Type Description
id integer The identifier for this exact Site
type string The type of object returned
name string A short string value for name of the Site
address string The address of the Site
city string The city of the Site
state string The state of the Site
zip_code string The zip code of the Site
country string The country abbreviation of the Site
code string An alpha numeric code to uniquely identify the Site

Create a Site

To create a new Site, the POST body can be sent as JSON. The site name field is required.

BODY='{
  name: "My new site",
  address: "123 Park Place",
  city: "New York",
  state: "NY",
  zip_code: "10001",
  country: "US",
  customer_id: 11
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/sites
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  name: "My new site",
  address: "123 Park Place",
  city: "New York",
  state: "NY",
  zip_code: "10001",
  country: "US",
  customer_id: 11
}

uri = URI("https://www.gocanvas.com/api/v3/sites")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

site_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  name: "My new site",
  address: "123 Park Place",
  city: "New York",
  state: "NY",
  zip_code: "10001",
  country: "US",
  customer_id: 11
};

fetch("https://www.gocanvas.com/api/v3/sites", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(site => console.log(site));

RESPONSE

{
  "id": 10,
  "name": "My new site",
  "address": "123 Park Place",
  "city": "New York",
  "state": "NY",
  "zip_code": "10001",
  "country": "US",
  "code": "NEW123"
}

HTTP Request

POST https://www.gocanvas.com/api/v3/sites

Request Body Parameters

Parameter Type Description
type string The type of object returned
name* string A short string value for name of the Site
address string The address of the Site
city string The city of the Site
state string The state of the Site
zip_code string The zip code of the Site
country** string The country abbreviation of the Site
code string An alpha numeric code to uniquely identify the Site
customer_id*** integer The ID of a Customer associated with the Company

* required field

** must be 2 letter country abbreviation

*** The Customer can be associated with multiple Sites.

Update a Site

To update an existing Site, the PATCH request body can be sent as JSON.

BODY='{
  "name": "Updated site name",
  "customer_id": 11,
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X PATCH \
  -d $BODY \
  https://www.gocanvas.com/api/v3/sites
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "name": "Updated site name",
  "customer_id": 11,
}

uri = URI("https://www.gocanvas.com/api/v3/sites")

json_request_body = request_body.to_json
req = Net::HTTP::Patch.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

site_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "name": "Updated site name",
  "customer_id": 11,
};

fetch("https://www.gocanvas.com/api/v3/sites", {
  method: "PATCH",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(site => console.log(site));

RESPONSE

{
  "message": "Site updated successfully"
}

HTTP Request

PATCH https://www.gocanvas.com/api/v3/sites/14

Request Body Parameters

Parameter Type Description
type string The type of object returned
name* string A short string value for name of the Site
address string The address of the Site
city string The city of the Site
state string The state of the Site
zip_code string The zip code of the Site
country** string The country abbreviation of the Site
code string An alpha numeric code to uniquely identify the Site
customer_id*** integer The ID of a Customer associated with the Company

* required field

** must be 2 letter country abbreviation

*** The Customer can be associated with multiple Sites.

Delete a Site

A Site can be deleted with a DELETE request.

By default, the DELETE request will soft-delete the site, which preserves the Site data but hides it from the web views. To permanently delete a Site, use the hard_delete=true parameter, e.g. DELETE https://www.gocanvas.com/api/v3/sites/10?hard_delete=true.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/sites/10
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/sites/10")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

site_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/sites/10", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(site => console.log(site));

RESPONSE

{
  "message": "Site 10 has been soft deleted successfully"
}

HTTP Request

DELETE https://www.gocanvas.com/api/v3/sites/14

Request Parameters

Parameter Type Description
hard_delete* boolean Will hard delete the Site record when set to true

* This is an optional URL parameter. If not provided, the Site will be soft deleted.

Submission

A Submission is a set of responses to a Form. Submissions are how GoCanvas clients transmit collected data.

The Submission object

EXAMPLE

{
  "id": 132394,
  "type": "submission",
  "client_guid": "156899451178900",
  "form_id": 346127,
  "submission_number": "00004",
  "submission_name": null,
  "created_at": "2023-05-16 00:47:51 UTC",
  "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C",
  "form": {
    "id": 346127,
    "type": "form",
    "name": "Basic Form",
    "description": null,
    "status": "published",
    "version": 1,
    "root_version_id": 346127
  },
  "department": {
    "id": 19134,
    "type": "department",
    "name": "First Department",
    "description": null
  }
}

Submissions must reference a Form. Clients must also generate a globally unique identifier (GUID) to allow GoCanvas servers to identify the submission and prevent duplicates. Responses within a Submission are the answers to questions or the responses to prompts against the Form.

For retrieving a form's entries used for Creating a Submission, see the minimal Form format documentation.

List all Submissions

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/submissions?form_id=346127
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/submissions?form_id=346127")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submissions_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/submissions?form_id=346127", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(submissions => console.log(submissions));

Users can view and filter a list of Submissions.

RESPONSE

[
  {
    "id": 6625009,
    "type": "submission",
    "client_guid": "049c1544-1ab5-41a1-a249-b8811cfa335c",
    "form_id": 346127,
    "submission_number": "00003",
    "submission_name": null,
    "created_at": "2023-10-13T14:10:34Z",
    "revision": true,
    "revised_at": "2025-04-09T16:43:57Z",
    "department_id": 13521,
    "user_id": 20079,
    "status": "completed",
    "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C"
  },
  {
    "id": 6624756,
    "type": "submission",
    "client_guid": "19b24c19-2247-4e05-92b1-0fd7f7510336",
    "form_id": 346127,
    "submission_number": "00002",
    "submission_name": null,
    "created_at": "2023-10-09T18:00:17Z",
    "revision": false,
    "revised_at": null,
    "department_id": 13521,
    "user_id": 20079,
    "status": "completed",
    "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C"
  },
  {
    "id": 6623946,
    "type": "submission",
    "client_guid": "d97c09ed-ce49-4a76-bcad-01508d4b6576",
    "form_id": 346127,
    "submission_number": "00001",
    "submission_name": null,
    "created_at": "2023-10-09T17:59:31Z",
    "revision": false,
    "revised_at": null,
    "department_id": 13521,
    "user_id": 20079,
    "status": "completed",
    "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C"
  }
]

HTTP Request

GET https://www.gocanvas.com/api/v3/submissions?form_id=346127

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1
form_id* integer The identifier for the Form the associated with the Submission
department_id** integer (optional) The identifier for the Department associated with the Submission (default department**)
user_id integer (optional) The identifier for the User who created the Submission
status enum (optional) The status filter of the Submission.
Can be all, completed, deleted, in-progress, overdue, rejected, handed-off, assigned, unassigned, custom, saved-to-cloud, or unfinished.
completed
hand_off string (optional) The name of the workflow handoff state to filter Submissions by. Required for the handed-off status. Learn more about GoCanvas Workflows.
custom_status string (optional) The label of the custom status to filter Submissions by. Required for the custom status. Learn more about GoCanvas custom submission statuses.
start_date*** datetime (optional) A DateTime value for the beginning bounds to search the Submissions' created_at
end_date*** datetime (optional) A DateTime value for the ending bounds to search the Submissions' created_at

* The provided form_id will match all versions of the Form for convenience.

** If no department_id is provided, the User's default department will be used.

*** start_date and end_date must be in the ISO-8601 format, e.g. 2024-01-30 or 2024-01-30T23:59:59 or 2024-01-30T23:59:59-04:00.

Submission Status Filters

Status Description
all Includes all submissions, regardless of their status.
completed Submissions that have been finalized and marked as complete.
deleted Submissions that have been deleted.
in-progress Submissions that are not yet completed. This is a superset of other statuses including statuses such as overdue, rejected, handed-off, assigned, and unassigned.
overdue Submissions for Forms using Follow-Ups that are incomplete and past their scheduled due date.
rejected Submissions for Forms using Workflow that have been rejected in a handoff.
handed-off Submissions for Forms using Workflow that have been handed off in a handoff. Requires the hand_off parameter.
assigned Submissions for Forms using Assignments that are assigned to a user.
unassigned Submissions for Forms using Assignments that are unassigned.
custom Submissions for Forms using Custom Statuses. Requires the custom_status parameter.
saved-to-cloud Submissions that have been saved to the cloud.
unfinished Submissions which are Unfinished in the process of uploading from the client.

Create a basic Submission

A basic text-only submission can be sent as JSON in the Request Body with a request header of Content-Type: application/json.

Submissions with media fields (photos, videos, or attachments) must use form-data, with a request header of Content-Type: multipart/form-data, as detailed in the Create a Submission with Media heading.

BODY='{
  guid: "c2703768-f672-42e9-a307-77abede123462",
  department_id: 19134,
  form: {
    id: 346127,
    version: 1
  },
  responses: [
    { "entry_id": 3777059, "displayed": true, "value": "Jane" },
    { "entry_id": 3777060, "displayed": true, "value": "Doe" },
    { "entry_id": 3777061, "displayed": true, "value": "Main Street" },
    { "entry_id": 3777062, "displayed": true, "value": "Boca Raton" },
    { "entry_id": 3777063, "displayed": true, "value": "FL" },
    { "entry_id": 3777064, "displayed": true, "value": "23456" },
  ],
  recipients: ["recipient.user@example.com"]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/submissions
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  guid: "c2703768-f672-42e9-a307-77abede123462",
  department_id: 19134,
  form: {
    id: 346127,
    version: 1
  },
  responses: [
    { "entry_id": 3777059, "displayed": true, "value": "Jane" },
    { "entry_id": 3777060, "displayed": true, "value": "Doe" },
    { "entry_id": 3777061, "displayed": true, "value": "Main Street" },
    { "entry_id": 3777062, "displayed": true, "value": "Boca Raton" },
    { "entry_id": 3777063, "displayed": true, "value": "FL" },
    { "entry_id": 3777064, "displayed": true, "value": "23456" },
  ],
  recipients: ["recipient.user@example.com"]
}

uri = URI("https://www.gocanvas.com/api/v3/submissions")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submission_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  guid: "c2703768-f672-42e9-a307-77abede123462",
  department_id: 19134,
  form: {
    id: 346127,
    version: 1
  },
  responses: [
    { "entry_id": 3777059, "displayed": true, "value": "Jane" },
    { "entry_id": 3777060, "displayed": true, "value": "Doe" },
    { "entry_id": 3777061, "displayed": true, "value": "Main Street" },
    { "entry_id": 3777062, "displayed": true, "value": "Boca Raton" },
    { "entry_id": 3777063, "displayed": true, "value": "FL" },
    { "entry_id": 3777064, "displayed": true, "value": "23456" },
  ],
  recipients: ["recipient.user@example.com"]
};

fetch("https://www.gocanvas.com/api/v3/submissions", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(submission => console.log(submission));

RESPONSE

{
  "id": 132394,
  "type": "submission",
  "client_guid": "156899451178900",
  "form_id": 346127,
  "submission_number": "00004",
  "submission_name": null,
  "created_at": "2023-05-16 00:47:51 UTC",
  "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C",
  "form": {
    "id": 346127,
    "type": "form",
    "name": "Basic Form",
    "description": null,
    "status": "published",
    "version": 1,
    "root_version_id": 346127
  },
  "department": {
    "id": 19134,
    "type": "department",
    "name": "First Department",
    "description": null
  }
}

HTTP Request

POST https://www.gocanvas.com/api/v3/submissions

Request Body Parameters

Parameter Type Description
body hash The JSON Submission body
guid string A globally unique identifier used to prevent duplicates
department_id§ integer The identifier to specify a Department.
form hash The Form to create the Submission to
form.id* integer The identifier to specify a Form
form.guid* string The identifier to specify a Form
form.version** integer The identifier to specify a Form
responses[] array A collection of responses against Form Entries
responses[].entry_id integer The unique identifier of an Entry
responses[].entry_guid string The unique guid of an Entry. An alternative to entry_id
responses[].displayed boolean Whether this Entry is displayed for user entry or calculated
responses[].value string The response data for the Entry
responses[].multi_key† string (optional) Reference to the looped value
responses[].content_guid‡ string (optional) A guid indicating an image or file will be uploaded
content_guid file (optional) An image or file to be uploaded
recipients array (optional) An array of email addresses to send a copy of the Submission to

* Either form.id or form.guid is required to identify the Form.

** When form.guid is specified, specifying a form.version is recommended.

† Only required for looped forms

‡ Only required for Media uploads, the attached file's guid must match with a responses[].content_guid value

§ Only required for forms that are shared across multiple departments, if one is not provided it will default to the form's original department

Create Submission with loops

Loop screens can be configured when designing a form, for information on how to configure loop screens, please refer to Loop Screens. Responses in loop screens use the multi_key field to identify the looped value.

BODY='{
  guid: "f4c7a1d9-8b1e-4d7f-9d5c-2d9e6b4e5a8f",
  department_id: 13521,
  form: {
    id: 4639578,
    version: 1,
  },
  responses: [
    { "entry_id": 543728076, "displayed": true, "value": "api.user@example.com" },
    { "entry_id": 543728077, "displayed": true, "value": "Smith Kane" },
    { "entry_id": 543728078, "displayed": true, "value": "555-414-1234" },
    { "entry_id": 543728080, "displayed": true, "value": "Priority" },
    { "entry_id": 543728079, "displayed": true, "multi_key": "Priority", "value": "High" },
    { "entry_id": 543728080, "displayed": true, "value": "Service Requested" },
    { "entry_id": 543728079, "displayed": true, "multi_key": "Service Requested", "value": "Painting" }
  ],
  recipients: ["recipient.user@example.com"]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/submissions
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  guid: "f4c7a1d9-8b1e-4d7f-9d5c-2d9e6b4e5a8f",
  department_id: 13521,
  form: {
    id: 4639578,
    version: 1,
  },
  responses: [
    { "entry_id": 543728076, "displayed": true, "value": "api.user@example.com" },
    { "entry_id": 543728077, "displayed": true, "value": "Smith Kane" },
    { "entry_id": 543728078, "displayed": true, "value": "555-414-1234" },
    { "entry_id": 543728080, "displayed": true, "value": "Priority" },
    { "entry_id": 543728079, "displayed": true, "multi_key": "Priority", "value": "High" },
    { "entry_id": 543728080, "displayed": true, "value": "Service Requested" },
    { "entry_id": 543728079, "displayed": true, "multi_key": "Service Requested", "value": "Painting" }
  ],
  recipients: ["recipient.user@example.com"]
}

uri = URI("https://www.gocanvas.com/api/v3/submissions")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submission_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  guid: "f4c7a1d9-8b1e-4d7f-9d5c-2d9e6b4e5a8f",
  department_id: 13521,
  form: {
    id: 4639578,
    version: 1,
  },
  responses: [
    { "entry_id": 543728076, "displayed": true, "value": "api.user@example.com" },
    { "entry_id": 543728077, "displayed": true, "value": "Smith Kane" },
    { "entry_id": 543728078, "displayed": true, "value": "555-414-1234" },
    { "entry_id": 543728080, "displayed": true, "value": "Priority" },
    { "entry_id": 543728079, "displayed": true, "multi_key": "Priority", "value": "High" },
    { "entry_id": 543728080, "displayed": true, "value": "Service Requested" },
    { "entry_id": 543728079, "displayed": true, "multi_key": "Service Requested", "value": "Painting" }
  ],
  recipients: ["recipient.user@example.com"]
};

fetch("https://www.gocanvas.com/api/v3/submissions", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(submission => console.log(submission));

RESPONSE

{
  "id": 145654,
  "type": "submission",
  "client_guid": "134278987678900",
  "form_id": 4639578,
  "submission_number": "00001",
  "submission_name": null,
  "created_at": "2023-05-16 00:47:51 UTC",
  "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C",
  "form": {
    "id": 4639578,
    "type": "form",
    "name": "Looped Screen Form",
    "description": null,
    "status": "published",
    "version": 1,
    "root_version_id": 4639578
  },
  "department": {
    "id": 13521,
    "type": "department",
    "name": "First Department",
    "description": null
  }
}

HTTP Request

POST https://www.gocanvas.com/api/v3/submissions

Request Body Parameters

Parameter Type Description
body hash The JSON Submission body
guid string A globally unique identifier used to prevent duplicates
department_id§ integer The identifier to specify a Department.
form hash The Form to create the Submission to
form.id* integer The identifier to specify a Form
form.guid* string The identifier to specify a Form
form.version** integer The identifier to specify a Form
responses[] array A collection of responses against Form Entries
responses[].entry_id integer The unique identifier of an Entry
responses[].entry_guid string The unique guid of an Entry. An alternative to entry_id
responses[].displayed boolean Whether this Entry is displayed for user entry or calculated
responses[].value string The response data for the Entry
responses[].multi_key† string (optional) Reference to the looped value
responses[].content_guid‡ string (optional) A guid indicating an image or file will be uploaded
content_guid file (optional) An image or file to be uploaded
recipients array (optional) An array of email addresses to send a copy of the Submission to

* Either form.id or form.guid is required to identify the Form.

** When form.guid is specified, specifying a form.version is recommended.

† Only required for looped forms

‡ Only required for Media uploads, the attached file's guid must match with a responses[].content_guid value

§ Only required for forms that are shared across multiple departments, if one is not provided it will default to the form's original department

Create Submission with media

Submissions with media fields (photos, videos, or attachments) require a multipart/form-data content type to upload a file associated with the submission. A content_guid for the response is necessary to link the uploaded file with its associated response, see Request Body Parameters below for more information.

curl -X POST \
     -u 'api.user@example.com:supersecretpassword' \
     --location 'https://www.gocanvas.com/api/v3/submissions' \
     --form 'guid="c2703768-f672-42e9-a307-77abede123462"' \
     --form 'department_id="19134"' \
     --form 'form="{\"id\": 346127, \"version\": 1}"' \
     --form 'responses="[
       {\"entry_id\": 3777059, \"displayed\": true, \"value\": \"Jane\"},
       {\"entry_id\": 3777060, \"displayed\": true, \"value\": \"Doe\"},
       {\"entry_id\": 3777061, \"displayed\": true, \"content_guid\": \"c3984328-f672-42e9-a307-77abede123462\"}
     ]"' \
     --form '{{c3984328-f672-42e9-a307-77abede123462}}=@"/path/to/image.jpg"'

require 'net/http'
require 'uri'
require 'json'

uri = URI.parse('https://www.gocanvas.com/api/v3/submissions')

request = Net::HTTP::Post.new(uri)
request.basic_auth('api.user@example.com', 'supersecretpassword')

form_data = {
  guid: 'c2703768-f672-42e9-a307-77abede123462',
  department_id: 19134,
  form: { id: 346127, version: 1 }.to_json,
  responses: [
    { entry_id: 3777059, displayed: true, value: 'Jane' },
    { entry_id: 3777060, displayed: true, value: 'Doe' },
    { entry_id: 3777061, displayed: true, content_guid: 'c3984328-f672-42e9-a307-77abede123462' }
  ].to_json
}
# Note: For file uploads, you may need to handle it differently as multipart upload
# This is a simplified version
form_data["c3984328-f672-42e9-a307-77abede123462"] = File.open('/path/to/image.jpg', 'rb')

request.set_form form_data, 'multipart/form-data'

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(request)
end

puts response.body

const form = new FormData();
form.append('guid', 'c2703768-f672-42e9-a307-77abede123462');
form.append('department_id', '19134');
form.append('form', JSON.stringify({ id: 346127, version: 1 }));
form.append('responses', JSON.stringify([
  { entry_id: 3777059, displayed: true, value: 'Jane' },
  { entry_id: 3777060, displayed: true, value: 'Doe' },
  { entry_id: 3777061, displayed: true, content_guid: 'c3984328-f672-42e9-a307-77abede123462' }
]));
form.append('c3984328-f672-42e9-a307-77abede123462', fs.createReadStream('/path/to/image.jpg'));


fetch('https://www.gocanvas.com/api/v3/submissions', {
  method: 'POST',
  headers: {
    'Authorization': 'Basic ' + btoa(username + ':' + password),
    'Content-Type': 'application/json'
  },
  body: form
}).then((response) => response.json())
.then((data => console.log(data) ))

RESPONSE

{
  "id": 132394,
  "type": "submission",
  "client_guid": "156899451178900",
  "form_id": 346127,
  "submission_number": "00004",
  "submission_name": null,
  "created_at": "2023-05-16 00:47:51 UTC",
  "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C",
  "form": {
    "id": 346127,
    "type": "form",
    "name": "Basic Form",
    "description": null,
    "status": "published",
    "version": 1,
    "root_version_id": 346127
  },
  "department": {
    "id": 19134,
    "type": "department",
    "name": "First Department",
    "description": null
  }
}

HTTP Request

POST https://www.gocanvas.com/api/v3/submissions

Request Body Parameters

Parameter Type Description
body hash The JSON Submission body
guid string A globally unique identifier used to prevent duplicates
department_id§ integer The identifier to specify a Department.
form hash The Form to create the Submission to
form.id* integer The identifier to specify a Form
form.guid* string The identifier to specify a Form
form.version** integer The identifier to specify a Form
responses[] array A collection of responses against Form Entries
responses[].entry_id integer The unique identifier of an Entry
responses[].entry_guid string The unique guid of an Entry. An alternative to entry_id
responses[].displayed boolean Whether this Entry is displayed for user entry or calculated
responses[].value string The response data for the Entry
responses[].multi_key† string (optional) Reference to the looped value
responses[].content_guid‡ string (optional) A guid indicating an image or file will be uploaded
content_guid file (optional) An image or file to be uploaded
recipients array (optional) An array of email addresses to send a copy of the Submission to

* Either form.id or form.guid is required to identify the Form.

** When form.guid is specified, specifying a form.version is recommended.

† Only required for looped forms

‡ Only required for Media uploads, the attached file's guid must match with a responses[].content_guid value

§ Only required for forms that are shared across multiple departments, if one is not provided it will default to the form's original department

Retrieve a Submission

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/submissions/691911
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/submissions/691911")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submission_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/submissions/691911", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(submission => console.log(submission));

Users can retrieve a Submission by its ID.

HTTP Request

GET https://www.gocanvas.com/api/v3/submissions/691911

RESPONSE

{
  "id": 691911,
  "type": "submission",
  "client_guid": "02ED5FB2-9C61-4F18-AB17-543547DF899B",
  "form_id": 81700,
  "submission_number": "00020",
  "submission_name": null,
  "created_at": "2024-05-16 17:27:57 UTC",
  "revision": true,
  "revised_at": "2025-04-09T16:43:57Z",
  "department_id": 27722,
  "user_id": 20079,
  "status": "completed",
  "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C",
  "responses": [
    {
      "id": 641486,
      "type": "Text Box",
      "entry_id": 3791371,
      "value": "Example text value",
      "label": "Destination",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641509,
      "type": "Text Box",
      "entry_id": 3791565,
      "value": "",
      "label": "Color",
      "export_label": null,
      "displayed": false
    },
    {
      "id": 641488,
      "type": "Integer",
      "entry_id": 3791373,
      "value": "23",
      "label": "Number",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641489,
      "type": "Signature",
      "entry_id": 3791374,
      "value": null,
      "label": "Approval Signature",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641490,
      "type": "Image Capture",
      "entry_id": 3791375,
      "value": "Binary data is not displayed",
      "label": "New Photo",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641491,
      "type": "Value List",
      "entry_id": 3791350,
      "value": "April",
      "label": "Select Month",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641492,
      "type": "Text Box",
      "entry_id": 3791348,
      "value": "John",
      "label": "First Name",
      "export_label": null,
      "multi_key": "April",
      "displayed": true
    },
    {
      "id": 641493,
      "type": "Text Box",
      "entry_id": 3791349,
      "value": "Smith",
      "label": "Last Name",
      "export_label": null,
      "multi_key": "April",
      "displayed": true
    }
  ]
}

Response Parameters

Parameter Type Description
id integer The identifier for this exact Submission
client_guid string A globally unique identifier used to prevent duplicates
form_id integer The version number of the Form that the Submission was created with
submission_number * string A Submission number generated based on the Form's submission numbering rules
revision ** boolean true indicates that the Submission has revisions
revised_at ** datetime The date and time when the Submission was last revised; null if it has not been revised
department_id integer The identifier for the Department associated with the Submission
user_id integer The unique identifier for the user who made the Submission
status string The status of the Submission.
device_guid string The unique identifier for the device that made the Submission
responses[] array A collection values for Entries
responses[].id integer The unique identifier of a Response
responses[].type string The data type of the Entry
responses[].entry_id integer The unique identifier of an Entry
responses[].value *** string The response data for the Entry
responses[].label string The label of the Entry
responses[].export_label string The export label of the Entry.
responses[].displayed boolean true indicates that this Entry is displayed for user entry, while false indicates that it was not displayed based on a condition
responses[].multi_key string (optional) Reference to the looped value

* More information on Submission Numbering can be found here

** When the revision field is true and revised_at is not null, additional information about the Submission Revisions can be retrieved from List of Revisions by Submission

*** Entries that are media fields (photos, videos, or attachments), return "Binary data is not displayed" if data was captured and null if it was not. Use the Retrieve a Value method to download the media field value.

Submission Statuses

Status Description
completed Submission has been finalized and marked as complete.
deleted Submission has been deleted.
overdue Submission for Forms using Follow-Ups that is incomplete and past its scheduled due date.
rejected Submission for Forms using Workflow that has been rejected in a handoff.
handed-off Submission for Forms using Workflow that has been handed off in a handoff.
assigned Submission for Forms using Assignments that is assigned to a user.
unassigned Submission for Forms using Assignments that is unassigned.
saved-to-cloud Submission that has been saved to the cloud.
unfinished Submission that is Unfinished in the process of uploading from the client.
(User defined) Submission status when using Forms using Custom Statuses may be user-defined values.

Retrieve a Submission by GUID

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submission_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(submission => console.log(submission));

Users can retrieve a Submission by its GUID.

HTTP Request

GET https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B

RESPONSE

{
  "id": 691911,
  "type": "submission",
  "client_guid": "02ED5FB2-9C61-4F18-AB17-543547DF899B",
  "form_id": 81700,
  "submission_number": "00020",
  "submission_name": null,
  "created_at": "2024-05-16 17:27:57 UTC",
  "revision": true,
  "revised_at": "2025-04-09T16:43:57Z",
  "department_id": 27722,
  "user_id": 20079,
  "status": "completed",
  "device_guid": "BB5E03A7-560C-4419-A99E-5388338C157C",
  "responses": [
    {
      "id": 641486,
      "type": "Text Box",
      "entry_id": 3791371,
      "value": "Example text value",
      "label": "Destination",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641509,
      "type": "Text Box",
      "entry_id": 3791565,
      "value": "",
      "label": "Color",
      "export_label": null,
      "displayed": false
    },
    {
      "id": 641488,
      "type": "Integer",
      "entry_id": 3791373,
      "value": "23",
      "label": "Number",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641489,
      "type": "Signature",
      "entry_id": 3791374,
      "value": null,
      "label": "Approval Signature",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641490,
      "type": "Image Capture",
      "entry_id": 3791375,
      "value": "Binary data is not displayed",
      "label": "New Photo",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641491,
      "type": "Value List",
      "entry_id": 3791350,
      "value": "April",
      "label": "Select Month",
      "export_label": null,
      "displayed": true
    },
    {
      "id": 641492,
      "type": "Text Box",
      "entry_id": 3791348,
      "value": "John",
      "label": "First Name",
      "export_label": null,
      "multi_key": "April",
      "displayed": true
    },
    {
      "id": 641493,
      "type": "Text Box",
      "entry_id": 3791349,
      "value": "Smith",
      "label": "Last Name",
      "export_label": null,
      "multi_key": "April",
      "displayed": true
    }
  ]
}

Response Parameters

Parameter Type Description
id integer The identifier for this exact Submission
client_guid string A globally unique identifier used to prevent duplicates
form_id integer The version number of the Form that the Submission was created with
submission_number * string A Submission number generated based on the Form's submission numbering rules
revision ** boolean true indicates that the Submission has revisions
revised_at ** datetime The date and time when the Submission was last revised; null if it has not been revised
department_id integer The identifier for the Department associated with the Submission
user_id integer The unique identifier for the user who made the Submission
status string The status of the Submission.
device_guid string The unique identifier for the device that made the Submission
responses[] array A collection values for Entries
responses[].id integer The unique identifier of a Response
responses[].type string The data type of the Entry
responses[].entry_id integer The unique identifier of an Entry
responses[].value *** string The response data for the Entry
responses[].label string The label of the Entry
responses[].export_label string The export label of the Entry.
responses[].displayed boolean true indicates that this Entry is displayed for user entry, while false indicates that it was not displayed based on a condition
responses[].multi_key string (optional) Reference to the looped value

* More information on Submission Numbering can be found here

** When the revision field is true and revised_at is not null, additional information about the Submission Revisions can be retrieved from List of Revisions by Submission

*** Entries that are media fields (photos, videos, or attachments), return "Binary data is not displayed" if data was captured and null if it was not. Use the Retrieve a Value method to download the media field value.

Submission Statuses

Status Description
completed Submission has been finalized and marked as complete.
deleted Submission has been deleted.
overdue Submission for Forms using Follow-Ups that is incomplete and past its scheduled due date.
rejected Submission for Forms using Workflow that has been rejected in a handoff.
handed-off Submission for Forms using Workflow that has been handed off in a handoff.
assigned Submission for Forms using Assignments that is assigned to a user.
unassigned Submission for Forms using Assignments that is unassigned.
saved-to-cloud Submission that has been saved to the cloud.
unfinished Submission that is Unfinished in the process of uploading from the client.
(User defined) Submission status when using Forms using Custom Statuses may be user-defined values.

List of Revisions by Submission

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/submissions/691911/revisions
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/submissions/691911/revisions")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submission_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/submissions/691911/revisions", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(submission => console.log(submission));

Users can retrieve the revisions for a specific Submission by its ID. Revisions provide a history of changes made to the values within the Submission.

The oldest revision is generated at the time of the first submission edit and corresponds to the original submission. It is assigned a revision_number of 0. Submissions with no revisions will return an empty array.

Revisions are returned in reverse chronological order, with the most recent revision appearing first in the list.

HTTP Request

GET https://www.gocanvas.com/api/v3/submissions/691911/revisions

RESPONSE

[
  {
    "id": 1002806,
    "type": "value_revision",
    "revision_number": 2,
    "user_id": 114,
    "user_email": "johndoe@example.com",
    "entry_id": 44890,
    "value_id": 52089,
    "previous_data": "Window repair",
    "new_data": "Fence repair",
    "created_at": "2025-04-09T16:43:89Z"
  },
  {
    "id": 1002805,
    "type": "value_revision",
    "revision_number": 1,
    "user_id": 114,
    "user_email": "johndoe@example.com",
    "entry_id": 44890,
    "value_id": 52089,
    "previous_data": "Roof repair",
    "new_data": "Window repair",
    "created_at": "2025-04-09T16:17:12Z"
  },
  {
    "id": 1002800,
    "type": "value_revision",
    "revision_number": 0,
    "user_id": 114,
    "user_email": "johndoe@example.com",
    "entry_id": null,
    "value_id": null,
    "previous_data": null,
    "new_data": null,
    "created_at": "2025-01-08T12:34:57Z"
  }
]


Response Parameters

Parameter Type Description
id integer The unique identifier for the revision
type string The type of object returned
revision_number integer The revision number, indicating the order of changes
user_id integer The unique identifier for the user who made the revision
user_email string The email of the user who made the revision
entry_id integer The unique identifier of an Entry
value_id integer The unique identifier of a Value
previous_data string The previous value before the revision
new_data string The new value after the revision
created_at datetime The timestamp when the revision was created

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1

Update a Submission

A submission that has already been created can be updated by sending a PATCH request to the submission endpoint with the submission ID. By passing value_ids and values in the request body, the submission can be updated with new values. By passing an empty string as the value, the value can be removed. A single image or signature can be updated by passing in a content_guid and the value_id in the request within the responses array body.

curl -X PATCH 'https://www.gocanvas.com/api/v3/submissions/691911' \
  -u 'api.user@example.com:supersecretpassword' \
  -H 'Content-Type: multipart/form-data' \
  -F 'responses="[
       {\"value_id\": 641346, \"delete": true},
       {\"value_id\": 641347, \"value\": \"Jane\"},
       {\"value_id\": 641348, \"value\": \"Doe\"},
       {\"value_id\": 641349, \"content_guid\": \"c3984328-f672-42e9-a307-77abede123462\"},      
       {\"value_id\": 641351, \"value\": \"Lat:50.669662,Lon:-79.957642,Acc:3.535534\"}
       { "entry_id": 3777061, "displayed": true, "value": "Main Street" }
     ]"' \
  -F 'c3984328-f672-42e9-a307-77abede123462=@/path/to/image.jpg'

# the value 641346 is a text field that will be removed since the `delete` key is set to true
# the values with ids 641347, 641348, 641349 and 641351 will be updated with the corresponding values
# a new value is added to the entry_id 3777061, which is a text field that will be displayed with the data `Main Street`

require 'net/http'
require 'uri'
require 'json'

uri = URI.parse('https://www.gocanvas.com/api/v3/submissions/691911')

request = Net::HTTP::Patch.new(uri)
request.basic_auth('api.user@example.com', 'supersecretpassword')

request.body = {
  responses: [
    { value_id: 641346, delete: true },
    { value_id: 641347, value: 'Jane' },
    { value_id: 641348, value: 'Doe' },
    { value_id: 641349, content_guid: 'c3984328-f672-42e9-a307-77abede123462' },
    { value_id: 641350 },
    { value_id: 641351, value: "Lat:50.669662,Lon:-79.957642,Acc:3.535534" },
    { entry_id: 3777061, displayed: true, value: "Main Street" }
  ]
}.to_json


form_data = {}
form_data["c3984328-f672-42e9-a307-77abede123462"] = File.open('/path/to/image.jpg', 'rb')

request.set_form form_data, 'multipart/form-data'

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(request)
end

puts response.body


# the value 641346 is a text field that will be removed since the `delete` key is set to `true`
# the values with ids 641347, 641348, 641349 and 641351 will be updated with the corresponding values
# a new value is added to the entry_id 3777061, which is a text field that will be displayed with the data `Main Street`

const form = new FormData();
form.append('responses', JSON.stringify([
  { value_id: 641346, delete: true },
  { value_id: 641347, value: 'Jane' },
  { value_id: 641348, value: 'Doe' },
  { value_id: 641349, content_guid: 'c3984328-f672-42e9-a307-77abede123462' },
  { value_id: 641351, value: "Lat:50.669662,Lon:-79.957642,Acc:3.535534" },
  { entry_id: 3777061, displayed: true, value: "Main Street" }
]));
form.append('c3984328-f672-42e9-a307-77abede123462', fs.createReadStream('/path/to/image.jpg'));

fetch('https://www.gocanvas.com/api/v3/submissions/691911', {
  method: 'PATCH',
  headers: {
    'Authorization': 'Basic ' + btoa(username + ':' + password),
  },
  body: form
})
.then(response => response.json())
.then(data => console.log(data))

//  the value 641346 is a text field that will be removed since the `delete` key is set to `true`
//  the values with ids 641347, 641348, 641349 and 641351 will be updated with the corresponding values
//  a new value is added to the entry_id 3777061, which is a text field that will be displayed with the data `Main Street`

HTTP Request

PATCH https://www.gocanvas.com/api/v3/submissions/691911

Request Body Parameters

Parameter Type Description
body hash The JSON Submission body
submission hash The Submission to update
submission.id* integer The identifier to specify a Submission
responses[] array A collection of responses against Submission Values
responses[].value_id integer The unique identifier of a Value
responses[].value string The response data for the Value
responses[].multi_key† string (optional) Reference to the looped value
responses[].content_guid‡ string (optional) A guid indicating an image or file will be uploaded
content_guid file (optional) An image of file to be uploaded

* A submission.id is required to identify the Submission.

† Only required for looped forms

‡ Only required for Image uploads, the attached file's guid must match with a responses[].content_guid value

Note: To update a GPS field, the value should be a string in the format of latitude,longitude,accuracy (e.g. "Lat:50.669662,Lon:-79.957642,Acc:3.535534").

Note: In order to update your GPS values correctly, make sure you are using EPSG:3857 projection to have your location correctly update and render"

Response

200 OK

Update a Submission with loops

Updating a submission with loops requires the multi_key field to be passed in the request body. The multi_key field is used to identify the looped value. When updating a "child" looped value, the multi_key field should be the same as the multi_key field of the "parent" looped value.

BODY='{
  "responses": [
    { "value_id": 641346, "value": "Priority" },
    { "value_id": 641345, "multi_key": "Priority", "value": "High" },
    { "value_id": 641348, "value": "Service Requested" },
    { "value_id": 641347, "multi_key": "Service Requested", "value": "Painting" }
  ]
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X PATCH \
  -d $BODY \
  https://www.gocanvas.com/api/v3/submissions
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "responses": [
    { "value_id": 641346, "value": "Priority" },
    { "value_id": 641345, "multi_key": "Priority", "value": "High" },
    { "value_id": 641348, "value": "Service Requested" },
    { "value_id": 641347, "multi_key": "Service Requested", "value": "Painting" }
  ]
}

uri = URI("https://www.gocanvas.com/api/v3/submissions")

json_request_body = request_body.to_json
req = Net::HTTP::Patch.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submission_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "responses": [
    { "value_id": 641346, "value": "Priority" },
    { "value_id": 641345, "multi_key": "Priority", "value": "High" },
    { "value_id": 641348, "value": "Service Requested" },
    { "value_id": 641347, "multi_key": "Service Requested", "value": "Painting" }
  ]
};

fetch("https://www.gocanvas.com/api/v3/submissions", {
  method: "PATCH",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(submission => console.log(submission));

HTTP Request

PATCH https://www.gocanvas.com/api/v3/submissions/691911

Request Body Parameters

Parameter Type Description
body hash The JSON Submission body
submission hash The Submission to update
submission.id* integer The identifier to specify a Submission
responses[] array A collection of responses against Submission Values
responses[].value_id integer The unique identifier of a Value
responses[].value string The response data for the Value
responses[].multi_key† string (optional) Reference to the looped value
responses[].content_guid‡ string (optional) A guid indicating an image or file will be uploaded
content_guid file (optional) An image of file to be uploaded

* A submission.id is required to identify the Submission.

† Only required for looped forms

‡ Only required for Image uploads, the attached file's guid must match with a responses[].content_guid value

Note: To update a GPS field, the value should be a string in the format of latitude,longitude,accuracy (e.g. "Lat:50.669662,Lon:-79.957642,Acc:3.535534").

Note: In order to update your GPS values correctly, make sure you are using EPSG:3857 projection to have your location correctly update and render"

Response

200 OK

Delete a Submission

A Submission can be deleted with a DELETE request.

By default, the DELETE request will soft-delete the submission, which preserves the Submission data but hides it from the web views. To permanently delete a Submission, use the hard_delete=true parameter, e.g. DELETE https://www.gocanvas.com/api/v3/submissions/691911?hard_delete=true.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/submissions/691911
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/submissions/691911")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submission_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/submissions/691911", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(submission => console.log(submission));

RESPONSE

{
  "message": "Submission 691911 has been soft deleted successfully"
}

HTTP Request

DELETE https://www.gocanvas.com/api/v3/submissions/691911

Request Parameters

Parameter Type Description
hard_delete* boolean Will hard delete the Submission record when set to true

* This is an optional parameter. If not provided, the submission will be soft deleted.

Delete a Submission by GUID

A Submission can be deleted with a DELETE request by GUID.

By default, the DELETE request will soft-delete the submission, which preserves the Submission data but hides it from the web views. To permanently delete a Submission, use the hard_delete=true parameter, e.g. DELETE https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B?hard_delete=true.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

submission_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(submission => console.log(submission));

RESPONSE

{
  "message": "Submission 691911 has been soft deleted successfully"
}

HTTP Request

DELETE https://www.gocanvas.com/api/v3/submissions/02ED5FB2-9C61-4F18-AB17-543547DF899B

Request Parameters

Parameter Type Description
hard_delete* boolean Will hard delete the Submission record when set to true

* This is an optional parameter. If not provided, the submission will be soft deleted.

User

A User is a GoCanvas user who belongs to a specific Company. To ensure proper access and permissions, each User must be assigned a valid Company role.

The User object

EXAMPLE

{
  "id": 114,
  "type": "user",
  "created_at": "2023-06-05 13:43:08 UTC",
  "first_name": "New",
  "last_name": "User",
  "login": "new.user@gocanvas.com",
  "enabled": true,
  "phone": "123-456-7890"
}

Parameter Type Description
id integer The unique User id
first_name string The first name of the User
last_name string The last name of the User
login string The email address of the User
enabled boolean Whether a user is allowed to login

List all Users

Users can view a list of all the Users associated with their Company.

To view a list of all Users per Department, see List all Department Users.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/users
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/users")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

users_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/users", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(users => console.log(users));

RESPONSE

[
  {
      "id": 20079,
      "type": "user",
      "created_at": "2023-06-16 23:09:20 UTC",
      "enabled": true,
      "first_name": "Sophie",
      "last_name": "Olufsen",
      "login": "sophie.olufsen@acmecorp.com",
      "address": "456 Market St",
      "address2": "Floor 3",
      "city": "San Francisco",
      "state": "CA",
      "zip": "94105"
  },
  {
      "id": 20122,
      "type": "user",
      "created_at": "2024-08-18 18:22:13 UTC",
      "enabled": true,
      "first_name": "Gregory",
      "last_name": "Johnson",
      "login": "gregory.johnson@acmecorp.com",
      "address": "123 Main St",
      "address2": "Suite 200",
      "city": "Denver",
      "state": "CO",
      "zip": "80202"
  }
]

HTTP Request

GET https://www.gocanvas.com/api/v3/users

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1
enabled boolean (optional) Returns only users that are enabled or disabled.
Returns all users if omitted.
null

Retrieve a User

Users can retrieve a User by its ID.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/users/20122
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/users/20122")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

user_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/users/20122", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(user => console.log(user));

HTTP Request

GET https://www.gocanvas.com/api/v3/users/20122

RESPONSE

{
    "id": 20122,
    "type": "user",
    "created_at": "2024-08-18 18:22:13 UTC",
    "enabled": true,
    "first_name": "Gregory",
    "last_name": "Johnson",
    "login": "gregory.johnson@acmecorp.com",
    "phone": "555-123-4567",
    "address": "123 Main St",
    "address2": "Suite 200",
    "city": "Denver",
    "state": "CO",
    "zip": "80202"
}

Response Parameters

Parameter Type Description
id integer The identifier for this User
created_at string A DateTime value of when the User was created
enabled boolean Whether the User is allowed to login
first_name string The first name of the User
last_name string The last name of the User
login string The email address of the User
phone string The phone number of the User
address string The street address of the User
address2 string The second line of the User's street address
city string The city of the User
state string The state or province of the User
zip string The postal code of the User

Create a User

To create a User in a Company, you'll need to pass basic information about the User: a unique email, a first_name, a last_name, and a department_role giving the User specific rights within a Department. If Departments are enabled for the Company, a valid department_id is also required to set the User's default department.

For more information on roles:

BODY='{
  "first_name": "New",
  "last_name": "User",
  "email": "new.user@gocanvas.com",
  "password": "SuperSecretPassword123!",
  "phone": "5555555555",
  "department_id": 1999,
  "department_role": "department_user",
  "account_role": "account_reporter"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/users
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "first_name": "New",
  "last_name": "User",
  "email": "new.user@gocanvas.com",
  "password": "SuperSecretPassword123!",
  "phone": "5555555555",
  "department_id": 1999,
  "department_role": "department_user",
  "account_role": "account_reporter"
}

uri = URI("https://www.gocanvas.com/api/v3/users")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

user_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "first_name": "New",
  "last_name": "User",
  "email": "new.user@gocanvas.com",
  "password": "SuperSecretPassword123!",
  "phone": "5555555555",
  "department_id": 1999,
  "department_role": "department_user",
  "account_role": "account_reporter"
};

fetch("https://www.gocanvas.com/api/v3/users", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(user => console.log(user));

HTTP Request

POST https://www.gocanvas.com/api/v3/users

Request Body Parameters

Parameter Type Description Options
department_role* string A valid department role to assign to the new User department_admin department_reporter department_user department_designer department_dispatcher
first_name string The first name of a new User
last_name string The last name of a new User
email string The unique email address of a new User
account_role** string (optional) A valid account role to assign to the new User account_admin account_reporter
password*** string (optional) The password of a new User
department_id**** integer (optional) The unique Department id to assign a new User to a specific Department
phone string (optional) The phone number of a new User
skip_welcome_email***** boolean (optional) Prevents welcome email from being sent to the new User when set to true true false

* All Companies have a default Department (when Departments are disabled, all Users belong to the default Department). department_role is used to set the User's role within a Department. When Departments are enabled, this role is specific to the specified department_id.

** account_role is only used when Departments are enabled for the Company. This sets the User's role for the entire Company and is not Department specific.

*** When password is specified, it must adhere to the company's password policy. When password is not specified, a secure password will be created automatically and a "Set your password" email will be sent to the email provided (not sent if skip_welcome_email is set to true).

**** department_id is required if Departments are enabled for the Company.

***** If skip_welcome_email is not specified, the default is false.

Response

RESPONSE

{
  "id": 114,
  "type": "user",
  "created_at": "2023-06-05 13:43:08 UTC",
  "first_name": "New",
  "last_name": "User",
  "login": "new.user@gocanvas.com",
  "enabled": true,
  "phone": "123-456-7890"
}

Parameter Type Description
id integer The unique User id for the new User
type string The type of object
first_name string The first name of the new User
last_name string The last name of the new User
login string The email address of the new User

Change User password

To change a User's password, you'll need to pass the id of the User and the new password. Must be an admin to change a User's password.

HTTP Request

curl -u api.user@example.com:supersecretpassword \
  -X PATCH \
  -H 'Content-Type: application/json' \
  -d '{"password": "SuperSecretPassword123!"}' \
  https://www.gocanvas.com/api/v3/users/114/change_password

require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/users/114/change_password")

req = Net::HTTP::Patch.new(uri)
req.basic_auth(username, password)
req.set_form_data({ password: "SuperSecretPassword123!" })
req["Content-Type"] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

const data = { "password": "SuperSecretPassword123!" }

fetch('https://www.gocanvas.com/api/v3/users/114/change_password', {
  method: 'PATCH',
  headers: {
    'Authorization': 'Basic ' + btoa(username + ':' + password),
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})
.then((response) => response.json())
.then((data => console.log(data) ))

PATCH https://www.gocanvas.com/api/v3/users/114/change_password

Request Body Parameters

Parameter Type Description
password* string The new password of a User

* Password must adhere to the company's password policy.

Response

204 No Content

Update User

To update a User, you will need to pass the id of the User and the new information. Either admin or user themself can update a User. Only fields listed in Request Body Parameters can be updated, others will be ignored.

HTTP Request

BODY='{
  "first_name": "New First Name"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X PATCH \
  -d $BODY \
  https://www.gocanvas.com/api/v3/users
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
  "first_name": "New First Name"
}

uri = URI("https://www.gocanvas.com/api/v3/users")

json_request_body = request_body.to_json
req = Net::HTTP::Patch.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

user_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
  "first_name": "New First Name"
};

fetch("https://www.gocanvas.com/api/v3/users", {
  method: "PATCH",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(user => console.log(user));

RESPONSE

{
  "message": "User updated successfully"
}

PATCH https://www.gocanvas.com/api/v3/users/114

Request Body Parameters

Parameter Type Description
first_name string (optional) New first name of a User
last_name string (optional) New last name of a User
phone string (optional) New phone number of a User
enabled* boolean (optional) Whether a user is allowed to login

* A disabled user may only be enabled if additional seats are available.

Values

Values represent the data that is collected in a submission.

Most values will be in-line within the Retrieve a Submission response. Values for media fields (photos, videos, or attachments) must be downloaded individually using this method.

Retrieve a Value

Users can download a Value's content for media fields (photos, videos, or attachments) by its ID through its submission.

HTTP Request

GET https://www.gocanvas.com/api/v3/submissions/691911/values/641490

curl -u api.user@example.com:supersecretpassword \
  https://www.gocanvas.com/api/v3/submissions/691911/values/641490 > value_641490.jpg

require 'net/http'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/submissions/691911/values/641490")

Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  req = Net::HTTP::Get.new(uri)
  req.basic_auth username, password

  http.request req do |response|
    open 'value-641490.jpg', 'wb' do |io|
      response.read_body do |chunk|
        io.write chunk
      end
    end
  end
end

let username = "api.user@example.com"
let password = "supersecretpassword"

fetch("https://www.gocanvas.com/api/v3/submissions/691911/values/641490", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
  },
})
  .then(response => {
      if (response.ok) {
          return response.blob();
      }
  })
  .then(blob => {
      let fileURL = URL.createObjectURL(blob);
      let fileLink = document.createElement('a');
      fileLink.href = fileURL;
      fileLink.download = 'value-641490.jpg';
      fileLink.click();
  })
  .catch((err) => {
      // handle error
      console.log(err);
  });

Webhooks

Webhooks are a customizable Integration Option that will notify your back end services of GoCanvas events in real time when you have time-sensitive needs based on your Form events.

The Webhook Object

EXAMPLE

{
        "id": 1,
        "type": "CustomIntegration",
        "event_type": "dispatch_create",
        "format": "json",
        "form_id": 346127,
        "push_url": "https://example.com/webhook",
        "push_tag": "webhook tag"
}

Webhooks are configured at a Form level and will persist across all versions of a Form. For example, any Webhook set up with version 2 of your Form will carry forward to versions 3 and so on.

When you add Webhook configurations to your forms, a payload containing some metadata about the event will be sent to the configured endpoint. There are five webhook event_types available:

Learn more about Webhooks here.

List all Webhooks

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/webhooks
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/webhooks")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

webhooks_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/webhooks", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(webhooks => console.log(webhooks));

User can view a list of all Webhooks associated with their Form.

RESPONSE

[
    {
        "id": 1,
        "type": "CustomIntegration",
        "event_type": "dispatch_create",
        "format": "json",
        "form_id": 346127,
        "push_url": "https://example.com/webhook",
        "push_tag": "dispatch webhook tag"
    },
    {
        "id": 2,
        "type": "CustomIntegration",
        "event_type": "submission_create",
        "format": "xml",
        "form_id": 346127,
        "push_url": "https://example.org/notify",
        "push_tag": "submission webhook tag"
    },
    {
        "id": 3,
        "type": "CustomIntegration",
        "event_type": "submission_edit",
        "format": "json",
        "form_id": 346127,
        "push_url": "https://example.org/notify-edit",
        "push_tag": "submission edit webhook tag"
    },
    {
        "id": 4,
        "type": "CustomIntegration",
        "event_type": "workflow_handoff_create",
        "format": "json",
        "form_id": 346127,
        "push_url": "https://example.net/user-webhook",
        "push_tag": " workflow webhook tag"
    },
    {
        "id": 5,
        "type": "CustomIntegration",
        "event_type": "submission_custom_status_change",
        "format": "json",
        "form_id": 346127,
        "push_url": "https://example.net/status-webhook",
        "push_tag": "submission status webhook tag"
    }
]

HTTP Request

GET https://www.gocanvas.com/api/v3/forms/346127/webhooks

Query Parameters

Parameter Type Description Default
page integer (optional) The page requested, see Pagination 1

Retrieve a Webhook

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X GET \
  https://www.gocanvas.com/api/v3/forms/346127/webhooks/1
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/346127/webhooks/1")

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

webhook_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/346127/webhooks/1", {
  method: "GET",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(webhook => console.log(webhook));

Users can retrieve a single Webhook associated with their Form by its ID.

RESPONSE

{
        "id": 1,
        "type": "CustomIntegration",
        "event_type": "dispatch_create",
        "format": "json",
        "form_id": 346127,
        "push_url": "https://example.com/webhook",
        "push_tag": "webhook tag"
}

HTTP Request

GET https://www.gocanvas.com/api/v3/forms/346127/webhooks/1

Response Parameters (Summary)

Parameter Type Description
id integer The unique identifier for the Webhook
type string The type of Integration Option
event_type string The event that triggers the Webhook
format string The format of the Webhook payload
form_id * integer The unique identifier for the associated Form
push_url string The URL to which the Webhook will send data
push_tag string A user-defined tag for the Webhook

* Webhook is tied to a root version of the Form. If the Form is updated, the Webhook remains associated with the root version. Using any version of the Form in the URL will return the same Webhook configuration.

Create a Webhook

Users can create a Webhook for a specific Form. In order to create dispatch_create(event_type) Webhook, Dispatch has to be enabled on the Form. In order to createworkflow_handoff_create Webhook, Workflow has to be enabled on the Form. In order to create submission_custom_status_change Webhook, Submission Status has to be enabled on the Form. Form can have only one Webhook per event_type.

BODY='{
"event_type": "dispatch_create",
"format": "json",
"push_url": "https://example.com/webhook",
"push_tag": "webhook tag"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  -d $BODY \
  https://www.gocanvas.com/api/v3/forms/346127/webhooks
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
"event_type": "dispatch_create",
"format": "json",
"push_url": "https://example.com/webhook",
"push_tag": "webhook tag"
}

uri = URI("https://www.gocanvas.com/api/v3/forms/346127/webhooks")

json_request_body = request_body.to_json
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

webhook_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
"event_type": "dispatch_create",
"format": "json",
"push_url": "https://example.com/webhook",
"push_tag": "webhook tag"
};

fetch("https://www.gocanvas.com/api/v3/forms/346127/webhooks", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(webhook => console.log(webhook));

RESPONSE

{
        "id": 1,
        "type": "CustomIntegration",
        "event_type": "dispatch_create",
        "format": "json",
        "form_id": 346127,
        "push_url": "https://example.com/webhook",
        "push_tag": "webhook tag"
}

HTTP Request

POST https://www.gocanvas.com/api/v3/forms/346127/webhooks

Request Body Parameters

Parameter Type Description
event_type* string The event that triggers the Webhook**
format* string The format of the Webhook payload***
push_url* string The URL to which the Webhook will send data
push_tag string A user-defined tag for the Webhook

* required field

** event_type can be dispatch_create, submission_create, submission_edit, workflow_handoff_create, or submission_custom_status_change

*** format can be json or xml for submission_create events, or json only for other event types

Test a Webhook

Users can test an existing Webhook for a specific Form to make sure integration is working before real events start triggering. This will send a test payload to the Webhook's push_url.

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X POST \
  https://www.gocanvas.com/api/v3/forms/346127/webhooks/1/test
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/346127/webhooks/1/test")

req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

webhook_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/346127/webhooks/1/test", {
  method: "POST",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(webhook => console.log(webhook));

RESPONSE

{
    "message": "Test webhook sent successfully",
    "response_code": 200,
    "response_body": "Webhook received and processed successfully",
    "test_payload": {
        "type": "dispatch_create",
        "form": {
            "id": 1,
            "name": "FORM_NAME",
            "guid": "FORM_GUID",
            "tag": ""
        },
        "dispatch_item": {
            "id": 1
        }
    }
}

HTTP Request

POST https://www.gocanvas.com/api/v3/forms/346127/webhooks/1/test

Response Parameters (Summary)

Parameter Type Description
message string Confirmation message about the test
response_code integer HTTP response code from the webhook endpoint
response_body string Response body received from the webhook endpoint
test_payload object The test payload that was sent to the webhook endpoint

Update a Webhook

Users can update an existing Webhook for a specific Form.

BODY='{
"push_tag": "updated webhook tag"
}'

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X PATCH \
  -d $BODY \
  https://www.gocanvas.com/api/v3/forms/346127/webhooks/1
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"
request_body = {
"push_tag": "updated webhook tag"
}

uri = URI("https://www.gocanvas.com/api/v3/forms/346127/webhooks/1")

json_request_body = request_body.to_json
req = Net::HTTP::Patch.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"
req.body = json_request_body

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

webhook_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";
const data = {
"push_tag": "updated webhook tag"
};

fetch("https://www.gocanvas.com/api/v3/forms/346127/webhooks/1", {
  method: "PATCH",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(webhook => console.log(webhook));

RESPONSE

{
  "message": "Webhook has been updated successfully"
}

HTTP Request

PATCH https://www.gocanvas.com/api/v3/forms/346127/webhooks/1

Request Body Parameters

Parameter Type Description
event_type string The event that triggers the Webhook**
format string The format of the Webhook payload***
push_url string The URL to which the Webhook will send data
push_tag string A user-defined tag for the Webhook

** event_type can be dispatch_create, submission_create, submission_edit, workflow_handoff_create, or submission_custom_status_change

*** format can be json or xml for submission_create events, or json only for other event types

Delete a Webhook

Users can delete an existing Webhook for a specific Form. By default, the DELETE request will only soft delete the Webhook which preserves the Webhook data and removes it from the view. To permanently delete the Webhook, include the hard_delete parameter with a value of true, e.g. DELETE https://www.gocanvas.com/api/v3/forms/346127/webhooks/1?hard_delete=true .

curl -u api.user@example.com:supersecretpassword \
  -H "Content-Type: application/json" \
  -X DELETE \
  https://www.gocanvas.com/api/v3/forms/346127/webhooks/1
require 'net/http'
require 'json'

username = "api.user@example.com"
password = "supersecretpassword"

uri = URI("https://www.gocanvas.com/api/v3/forms/346127/webhooks/1")

req = Net::HTTP::Delete.new(uri)
req['Authorization'] = "Basic " + Base64.strict_encode64("#{username}:#{password}")
req['Content-Type'] = "application/json"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

webhook_json = JSON.parse(res.body)
const username = "api.user@example.com";
const password = "supersecretpassword";

fetch("https://www.gocanvas.com/api/v3/forms/346127/webhooks/1", {
  method: "DELETE",
  headers: {
    Authorization: "Basic " + btoa(username + ":" + password),
    "Content-Type": "application/json",
  }
})
  .then(response => response.json())
  .then(webhook => console.log(webhook));

RESPONSE

{
  "message": "Webhook 1 has been soft deleted successfully"
}

HTTP Request

DELETE https://www.gocanvas.com/api/v3/forms/346127/webhooks/1

Request Parameters

Parameter Type Description
hard_delete* boolean Will hard delete the Webhook record when set to true

* This is an optional URL parameter. If not provided, the Webhook will be soft deleted.