Offorte API
Welcome to the Offorte API! Here you'll find all the documentation to get your started with integrating your application with Offorte.
Making a request
All URLs start with https://connect.offorte.com/api/v1/{account_name}. Only HTTPS is supported and the path is prefixed with /api/v1/your_account_name.
We use JSON for all API data, there is no root element and we use snake_case for object keys. You have to send the Content-Type header "Content-Type: application/json; charset=utf-8" when you do a POST, PATCH or PUT.
Your account name is the subdomain name in your Offorte account address: https://companyname.offorte.com/
Pagination
For the list requests we paginate the results. The ratio is 50 items per page. Add the request param page to your request. For example: https://connect.offorte.com/api/v1/{account_name}/companies/?page=2
Rate limit
To prevent a too heavy load on our servers we've implemented a rate limit of 30 requests per 1 minute.
Errors
The Offorte API uses the following error codes:
Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API authorisation is wrong. |
403 | Forbidden -- The item requested is hidden. |
404 | Not Found -- The item could not be found. |
405 | Method Not Allowed -- You tried to access an item with an invalid method. |
410 | Gone -- The item requested has been removed from our servers. |
429 | Too Many Requests -- You're requesting too many items! Slow down! |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
Legacy support / Deprecated fields
We choose to avoid breaking changes in the API. Sometimes properties get renamed or extended with functionality. This results into us returning legacy fields which are not shown in the docs and not advisable to use. We might remove those somewhere in the future.
Terms of use
The Offorte General Terms and User Terms applies on the use of the API.
Authentication
To authenticate your application we support OAuth2. So pass allong an OAuth2 bearer token with your API request and you'll be fine.
OAuth2
OAuth2 is a secure option that allows third-party applications to access a server without passing user credentials or API keys. There are a lot of resources online on OAuth2
1. Implement an OAuth2 library.
2. Register your app within your Offorte Account (settings => API). Here you can create your app and will be assigned a client_id and client_secret. Also provide a redirect_uri where we optionally can send the verification code.
3. Request authorization on the following url: https://{your_account_name}.offorte.com/oauth2/authorize and add the following GET params to your request:
Param | Value |
---|---|
client_id | {YOUR_CLIENT_ID} |
redirect_uri | {YOUR_REDIRECT_URL} |
response_type | 'code' |
4. Request an access token by doing a POST on the following url: https://{your_account_name}.offorte.com/oauth2/token and add the following params to your request, we will return the access code in json:
Param | Value |
---|---|
client_id | {YOUR_CLIENT_ID} |
client_secret | {YOUR_CLIENT_SECRET} |
redirect_uri | {YOUR_REDIRECT_URL} |
code | {CODE} (obtained in step 3) |
grant_type | 'authorization_code' |
5. Try to make an authorized request to https://connect.offorte.com/api/v1/{your_account_name}/hello Use the access code obtained in step 4 as a header Bearer authentication code
Refresh tokens
When your access token expires (30 days), you can generate a new access token using the refresh token you received in conjunction with your access token.
curl -X POST https://{your_account_name}.offorte.com/oauth2/refresh-token \
--data "grant_type=refresh_token" \
--data "client_id=XXX" \
--data "client_secret=XXX" \
--data "refresh_token=XXX"
Webhooks
Offorte can notify your application by using webhooks. A webhook consists of a https payload URL to be called and a list of events that will trigger calls. Rather than pulling information via our API, webhooks will push information to your endpoint. When one of those events is triggered (for example a new company is added), Offorte will send this notification as HTTP POST request, with a JSON body, to the endpoint(s) you specify.
If you're new to webhooks, read this guide to learn more.
Offorte will try to call the payload URL up to 10 times before deactivating the webhook. The duration between attempts will grow exponentially longer to give your application time to recover. Please respond with a 2xx range HTTP status code, without redirects, so we know the response was succesful. The timeout for calling a payload URL is 5 seconds.
The maximum limit of webhooks is 10 different webhooks per account. We are throttling the events and remove duplicates from a batch so that no overloading is happpening. For example, when you update a certain company twice in 2 seconds, we will only send one event.
By default an URL is subscribed to "all" events. You can also subscribe to individual events. The webhooks get triggered by the following events.
Event | Info |
---|---|
all | Default; Triggers on all events |
company_created | |
company_updated | |
company_deleted | |
company_contact_created | |
company_contact_updated | |
company_contact_deleted | |
proposal_created | |
proposal_details_updated | proposal detail changes: name, totalprice, status, contacts, versions, attachments |
proposal_deleted | |
proposal_send | |
proposal_won | |
proposal_lost | proposal closed |
proposal_viewed | proposal viewed firsttime or after 14 days of no activity and then viewed again |
proposal_comment_received | when a prospect asks a question through the proposal viewer |
product_directory_created | |
product_directory_updated | |
product_directory_deleted | |
product_created | |
product_updated | |
product_deleted |
Payloads
All payloads have the same JSON structure where the data field contains the details of the updated object. The data object generally has the same structure as documented in the rest api for the targeted entity/subject.
{
type: 'company_updated',
date_created: '2020-10-16 18:05:00',
data: {
...
}
}
Endpoints
Go to the 'Webhooks' section below to learn how to manage the webhooks.
Automations
List all automations sets
GET /automations/sets
Returns a list of automations sets as defined in the settings
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/automations/sets \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"name": "Example Inc"
}
]
Account
Users list
GET /account/users/
Returns a list of active account users.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/account/users/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"email": "[email protected]",
"firstname": "Chuck",
"lastname": "Norris",
"phone": "+31 76 12344567",
"jobtitle": "CEO",
"date_lastlogin": "2020-06-15 18:05:59"
}
]
Contacts
List all companies
GET /companies
Returns a paginated list of companies.
Searching on name can be done by using the optional query
parameter
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/companies \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"name": "Example Inc",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"fax": "+31 76 12344567",
"email": "[email protected]",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example",
"coc_number": "12345678",
"vat_number": "NL123455678",
"people": [
{
"id": 1234,
"company_id": 1234,
"firstname": "Chuck",
"lastname": "Norris",
"fullname": "Chuck Norris",
"salutation": "Mr",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"mobile": "+31 76 12344567",
"email": "[email protected]",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example"
}
]
}
]
Get company details
GET /companies/:id/
Returns all company details
Deprecated fields: proposal_status, proposal_name, account_company_user_id.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/companies/:id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
{
"id": 1234,
"name": "Example Inc",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"fax": "+31 76 12344567",
"email": "[email protected]",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example",
"coc_number": "12345678",
"vat_number": "NL123455678",
"people": [
{
"id": 1234,
"company_id": 1234,
"firstname": "Chuck",
"lastname": "Norris",
"fullname": "Chuck Norris",
"salutation": "Mr",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"mobile": "+31 76 12344567",
"email": "[email protected]",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example"
}
],
"proposals": [
{
"id": 1234,
"account_user_id": null,
"company_id": 1234,
"company_name": "Example Inc",
"name": "Proposal you can't refuse",
"status": "won",
"price_total": "$999.99",
"proposal_nr": "nr 000123",
"version_id": 1234,
"date_created": "15 jun 2018 (06:49)"
}
]
}
Delete company
DELETE /companies/:id/
Deletes a company
Request example
curl -X DELETE https://connect.offorte.com/api/v1/{account_name}/companies/:id/
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
Update company
PATCH /companies/:id/
Updates the company details with the provided attributes. Other (unprovided) attributes remain unchanged
Request example
curl -X PATCH https://connect.offorte.com/api/v1/{account_name}/companies/:id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"id": 1234,
"name": "Example Inc",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"fax": "+31 76 12344567",
"email": "[email protected]",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example",
"coc_number": "12345678",
"vat_number": "NL123455678"
}
Parameters
name | type | description |
---|---|---|
id | integer | |
name | string | |
street | string | |
zipcode | string | |
city | string | |
state | string | |
country | string | |
phone | string | |
fax | string | |
string | ||
internet | string | |
string | ||
string | ||
string | ||
coc_number | string | |
vat_number | string |
Create company
POST /companies/
Creates a new company
Request example
curl -X POST https://connect.offorte.com/api/v1/{account_name}/companies/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"id": 1234,
"name": "Example Inc",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"fax": "+31 76 12344567",
"email": "[email protected]",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example",
"coc_number": "12345678",
"vat_number": "NL123455678"
}
Parameters
name | type | description |
---|---|---|
id | integer | |
name | string | |
street | string | |
zipcode | string | |
city | string | |
state | string | |
country | string | |
phone | string | |
fax | string | |
string | ||
internet | string | |
string | ||
string | ||
string | ||
coc_number | string | |
vat_number | string |
List people
GET /companies/:id/people/
Returns a paginated list of the people in a company.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/companies/:id/people/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"company_id": 1234,
"email": "[email protected]",
"firstname": "Chuck",
"lastname": "Norris",
"fullname": "Chuck Norris",
"salutation": "Mr",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"mobile": "+31 76 12344567",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example"
}
]
Create people
POST /companies/:id/people/
Creates a new person in a company. Fullname and e-mail are required
Request example
curl -X POST https://connect.offorte.com/api/v1/{account_name}/companies/:id/people/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"email": "[email protected]",
"firstname": "Chuck",
"lastname": "Norris",
"fullname": "Chuck Norris",
"salutation": "Mr",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"mobile": "+31 76 12344567",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example"
}
Parameters
name | type | description |
---|---|---|
string | ||
firstname | string | |
lastname | string | |
fullname | string | |
salutation | string | |
street | string | |
zipcode | string | |
city | string | |
state | string | |
country | string | |
phone | string | |
mobile | string | |
internet | string | |
string | ||
string | ||
string |
Get people details
GET /companies/:id/people/:people_id/
Returns all details of a person
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/companies/:id/people/:people_id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
{
"id": 1234,
"company_id": 1234,
"email": "[email protected]",
"firstname": "Chuck",
"lastname": "Norris",
"fullname": "Chuck Norris",
"salutation": "Mr",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"mobile": "+31 76 12344567",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example"
}
Delete people
DELETE /companies/:id/people/:people_id/
Deletes a person
Request example
curl -X DELETE https://connect.offorte.com/api/v1/{account_name}/companies/:id/people/:people_id/
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
Update people
PATCH /companies/:id/people/:people_id/
Updates the person details with the provided attributes. Other (unprovided) attributes remain unchanged
Request example
curl -X PATCH https://connect.offorte.com/api/v1/{account_name}/companies/:id/people/:people_id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"email": "[email protected]",
"firstname": "Chuck",
"lastname": "Norris",
"fullname": "Chuck Norris",
"salutation": "Mr",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"mobile": "+31 76 12344567",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example"
}
Parameters
name | type | description |
---|---|---|
string | ||
firstname | string | |
lastname | string | |
fullname | string | |
salutation | string | |
street | string | |
zipcode | string | |
city | string | |
state | string | |
country | string | |
phone | string | |
mobile | string | |
internet | string | |
string | ||
string | ||
string |
Settings
Design templates list
GET /settings/design-templates/
Returns a list of design templates.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/settings/design-templates/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"name": "My template"
}
]
Email templates list
GET /settings/email-templates/
Returns a list of email templates.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/settings/email-templates/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"name": "My template"
}
]
Text templates list
GET /settings/text-templates/
Returns a list of text templates.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/settings/text-templates/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"name": "My template"
}
]
VAT groups list
GET /settings/vat-groups/
Returns a list of VAT groups.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/settings/vat-groups/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"name": "My template",
"vat": 21,
"label": "My text label"
}
]
Products
List product directories
GET /products/directories
List the product directories
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/products/directories \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"name": "Example Inc"
}
]
Delete product directory
DELETE /products/directories/:directory_id/
Deletes a product directory. The directory should not contain any products, otherwise the request will fail.
Request example
curl -X DELETE https://connect.offorte.com/api/v1/{account_name}/products/directories/:directory_id/
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
Update product directory
PATCH /products/directories/:directory_id/
Updates the directory with the provided attributes.
Request example
curl -X PATCH https://connect.offorte.com/api/v1/{account_name}/products/directories/:directory_id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"name": "Example Inc"
}
Parameters
name | type | description |
---|---|---|
name | string |
Create product directory
POST /products/directories/
Creates a new product directory
Request example
curl -X POST https://connect.offorte.com/api/v1/{account_name}/products/directories/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"name": "Example Inc"
}
Parameters
name | type | description |
---|---|---|
name | string |
List products
GET /products/:directory_id/
List the products for a directory.
Deprecated fields: optional.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/products/:directory_id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"sku": "abc12345678",
"price": "1000",
"vat_id": 1234,
"selectable": "check",
"recurring": "month",
"name": "Example Inc",
"descr_short": "This is a description",
"vat_percentage": 21
}
]
Create product
POST /products/:directory_id/
Creates a new product.
Deprecated fields: optional.
Request example
curl -X POST https://connect.offorte.com/api/v1/{account_name}/products/:directory_id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8' \ -H 'Accept: application/json; charset=utf-8'
Body
{
"sku": "abc12345678",
"price": "1000",
"vat_id": 1234,
"selectable": "check",
"recurring": "month",
"name": "Example Inc",
"descr_short": "This is a description"
}
Parameters
name | type | description |
---|---|---|
sku | string | |
price | float | |
vat_id | integer | |
selectable | string | Row is optional to choose by the customer. Check is multiple choice, Radio is single choice. Types: check,radio,false |
recurring | string | Row is recurring and from type: month |
name | string | |
descr_short | string |
Response example
{
"product_id": 1234
}
Update product
PATCH /product/:product_id/
Updates the product with the provided attributes.
Deprecated fields: optional.
Request example
curl -X PATCH https://connect.offorte.com/api/v1/{account_name}/product/:product_id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"sku": "abc12345678",
"price": "1000",
"vat_id": 1234,
"selectable": "check",
"recurring": "month",
"name": "Example Inc",
"descr_short": "This is a description",
"directory_id": 1234
}
Parameters
name | type | description |
---|---|---|
sku | string | |
price | float | |
vat_id | integer | |
selectable | string | Row is optional to choose by the customer. Check is multiple choice, Radio is single choice. Types: check,radio,false |
recurring | string | Row is recurring and from type: month |
name | string | |
descr_short | string | |
directory_id | integer |
Delete product
DELETE /products/:product_id/
Deletes a product
Request example
curl -X DELETE https://connect.offorte.com/api/v1/{account_name}/products/:product_id/
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
Proposals
List all proposals
GET /proposals/:status
Returns a paginated list of proposals by status (edit|open|won|lost|closed).
Searching can be done by using the optional query
parameter, the provided status will then be ignored.
Deprecated fields: total_price, total_price_override.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/proposals/:status \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"account_user_id": 1234,
"company_id": 1234,
"company_name": "Example Inc",
"name": "Proposal you can't refuse",
"status": "won",
"price_total": "$999.99",
"price_total_original": 999.99,
"price_total_override": 999.99,
"proposal_nr": "nr 000123",
"version_id": 1234,
"date_created": "15 jun 2018 (06:49)"
}
]
Get proposal details
GET /proposals/:id/details/
Returns all proposal details
Deprecated fields: type, pages_total, language, pricetable-rows: count, userinput_count, userinput_optional, userinput_optional_checked.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/proposals/:id/details/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
{
"id": 1234,
"account_user_id": 1234,
"account_user_name": "Elon Musk",
"account_user_email": "[email protected]",
"name": "Proposal you can't refuse",
"status": "won",
"remarks": "Make some modifications as requested by Vegan Seagal",
"price_total": "$999.99",
"price_total_original": 999.99,
"price_total_override": 999.99,
"date_modified": "15 jun 2018 (06:49)",
"proposal_nr": "nr 000123",
"proposal_language": "en",
"design_template_id": 1234,
"text_template_id": 1234,
"company": {
"id": 1234,
"name": "Example Inc",
"street": "Ginnekenweg 1",
"zipcode": "4800AA",
"city": "Breda",
"state": "Noord-Brabant",
"country": "the Netherlands",
"phone": "+31 76 12344567",
"fax": "+31 76 12344567",
"email": "[email protected]",
"internet": "https://www.example.com",
"linkedin": "https://linkedin.com/example",
"facebook": "https://facebook.com/example",
"twitter": "https://twitter.com/example",
"coc_number": "12345678",
"vat_number": "NL123455678"
},
"comments": [
{
"id": 1234,
"date": "15 jun 2018 (06:49)",
"comment": "Are there no surprises in the costs?",
"type": "client",
"firstname": "Chuck",
"lastname": "Norris",
"email": "[email protected]",
"company_name": "Example Inc"
}
],
"logs": {
"summary": {
"views": 2,
"pdf": 0,
"recent_view": "15 jun 2018 (06:49)",
"last_modified_date": "15 jun 2018 (06:49)",
"last_modified_user": "2020-06-15 18:05:59"
},
"history": [
{
"date": "15 jun 2018 (06:49)",
"person": "Chuck Norris",
"action": "proposal: viewed pdf",
"type": "client"
}
]
},
"emails": [
{
"id": 1234,
"date_sended": "15 jun 2018 (06:49)",
"proposal_version_nr": 1234,
"message": "Dear {company_people_firstname}, hereby you receive our proposal for ...",
"sended_by": "Johnny Vegas",
"receivers": [
{
"fullname": "Chuck Norris",
"email": "[email protected]"
}
]
}
],
"receivers": [
{
"id": 1234,
"fullname": "Chuck Norris",
"email": "[email protected]",
"pass": "https://demo.offorte.com/viewer/123/?proposalpass=123",
"signature_required": 1,
"signature_allowed": 1
}
],
"content": {
"pricetables": [
{
"id": "pricetable1",
"subtotal": 1000,
"total": 100,
"settings": {
"vat_default_percentage": 21,
"vat_hidden": false,
"rows_include_vat": false
},
"rows": [
{
"id": 1234,
"content": "<p>Product Awesome</p>",
"quantity": 3,
"price": 100,
"subtotal": 300,
"vat_percentage": 21,
"type": "price",
"discount_type": "amount",
"discount_value": 10,
"product_id": 990,
"sku": "2452345",
"selectable": "check",
"user_selected": true,
"user_quantity": true,
"recurring_type": "month",
"recurring_include_in_totals": true,
"unique_id": "identifier-1234"
}
],
"vat": [
{
"percentage": 21,
"total": 100,
"group_name": "Vat21"
}
]
}
]
}
}
Update proposal
PATCH /proposals/:id/details/
Updates the proposal details with the provided attributes. Other (unprovided) attributes remain unchanged
Request example
curl -X PATCH https://connect.offorte.com/api/v1/{account_name}/proposals/:id/details/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"account_user_id": 1234,
"company_contacts": [
1
],
"company_id": 1234,
"design_template_id": 1234,
"name": "Proposal you can't refuse",
"price_total": 999.99,
"status": "won",
"text_template_id": 1234
}
Parameters
name | type | description |
---|---|---|
account_user_id | integer | The proposal is assigned to this user and will be send out in name of this user |
company_contacts | array | List with company contact id's who are going to receive the proposal; Make sure they got an email filled in |
company_id | integer | The proposal is assigned to this company |
design_template_id | integer | Design template id |
name | string | Name of the proposal |
price_total | float | Proposal value as calculated by pricetables |
status | string | Proposal status. Possible values: edit,open,won,lost,closed |
text_template_id | integer | Text template id |
Create proposal
POST /proposals/
Create a new proposal.
Content: Pricetables
Optionally you have the option to add rows to pricetables. Make sure you updated the 'Unique ID' field through the pricetable settings in your proposal template. Then you can target this pricetable to add rows to.
Fields per row type:
type | fields |
---|---|
price | type, content, quantity, price, vat_percentage, selectable (false, check, radio), user_selected, user_quantity, discount_type (false, percentage, amount), discount_value, recurring_type (false, month, year), recurring_include_in_totals, hide_price, hide_quantity, unique_id, product_id, sku |
discount | type, content, discount_type (percentage, amount), discount_value |
subtotal | type, content |
title | type, content |
Deprecated fields: row-type-price: count, userinput_optional, userinput_optional_checked, userinput_count; row-type-discount: discount
Request example
curl -X POST https://connect.offorte.com/api/v1/{account_name}/proposals/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8' \ -H 'Accept: application/json; charset=utf-8'
Body
{
"account_user_id": 1234,
"company_contacts": [
1
],
"company_id": 1234,
"design_template_id": 1234,
"automations_set_id": 1234,
"text_template_id": 1234,
"name": "Proposal you can't refuse",
"proposal_template_id": 1234,
"content": {
"pricetables": [
{
"id": "pricetable1",
"rows": [
{
"type": "price",
"content": "<p>Product Awesome</p>",
"quantity": 3,
"price": 100,
"vat_percentage": 21,
"selectable": "check",
"user_selected": true,
"user_quantity": true,
"recurring_type": "month",
"recurring_include_in_totals": true,
"discount_type": "amount",
"discount_value": 10,
"unique_id": "identifier-1234",
"hide_price": true,
"hide_quantity": true,
"product_id": 990,
"sku": "2452345"
}
]
}
]
}
}
Parameters
name | type | description |
---|---|---|
account_user_id | integer | The proposal is assigned to this user and will be send out in name of this user |
company_contacts | array | List with company contact id's who are going to receive the proposal; Make sure they got an email filled in |
company_id | integer | The proposal is assigned to this company |
design_template_id | integer | Design template id |
automations_set_id | integer | Automation set id |
text_template_id | integer | Text template id |
name | string | Name of the proposal |
proposal_template_id | integer | Proposal favorite template id |
content | object |
Response example
{
"proposal_id": 1234,
"proposal_version_id": 1234
}
Send proposal
POST /proposals/:id/send/
Send a proposal
Request example
curl -X POST https://connect.offorte.com/api/v1/{account_name}/proposals/:id/send/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8' \ -H 'Accept: application/json; charset=utf-8'
Body
{
"password_reset": false,
"send_method": "self",
"send_message": "Hi {company_people_firstname},\\nHere is an offer you can't refuse...",
"send_message_id": 1234
}
Parameters
name | type | description |
---|---|---|
password_reset | boolean | Optional: Reset the existing passwords when proposal was send before |
send_method | string | Optional: Choose if you want to send it through Offorte or send the proposal your self. Defaults to 'offorte'. Possible values: offorte,self |
send_message | string | The actual message you want to send in plain text. If not provided you must provide the 'send_message_id' |
send_message_id | integer | The id of the email template you want to use as the accompanying message |
Response example
{
"receivers": [
{
"id": 1234,
"fullname": "Chuck Norris",
"email": "[email protected]",
"proposal_link": "https://youraccount.offorte.com/viewer/1234/?proposalpass=1234",
"signature_required": 0,
"signature_allowed": 1
}
]
}
Delete proposal
DELETE /proposals/:id/
Deletes a proposal
Request example
curl -X DELETE https://connect.offorte.com/api/v1/{account_name}/proposals/:id/
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
Favorite templates
GET /favorites/proposals/
Returns a list of proposal favorites (templates).
Deprecated fields: type,config_language_id,proposal_tpl_id.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/favorites/proposals/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"name": "My template",
"text_template_id": 1234,
"design_template_id": 1234
}
]
Webhooks
List all webhooks
GET /webhooks/
Returns a list of webhooks.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/webhooks/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
[
{
"id": 1234,
"active": true,
"payload_url": "https://example.com/incoming",
"payload_content_type": "json",
"date_created": "2020-06-15 18:05:59",
"date_modified": "2020-06-15 18:05:59",
"date_failed": "2020-06-15 18:05:59",
"events": [
"company_created"
]
}
]
Create webhook
POST /webhooks/
Creates a new webhook
Request example
curl -X POST https://connect.offorte.com/api/v1/{account_name}/webhooks/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"payload_url": "https://example.com/incoming",
"payload_content_type": "json",
"active": true,
"events": [
"company_created"
]
}
Parameters
name | type | description |
---|---|---|
payload_url | string | Url where the data will be posted to; must be a full https url |
payload_content_type | string | Content type header: json |
active | boolean | Is it active or not |
events | array | Events to subscribe to |
Get webhook details
GET /webhooks/:id/
Returns the webhook details.
Request example
curl -X GET https://connect.offorte.com/api/v1/{account_name}/webhooks/:id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Accept: application/json; charset=utf-8'
Response example
{
"id": 1234,
"active": true,
"payload_url": "https://example.com/incoming",
"payload_content_type": "json",
"date_created": "2020-06-15 18:05:59",
"date_modified": "2020-06-15 18:05:59",
"date_failed": "2020-06-15 18:05:59",
"events": [
"company_created"
]
}
Delete webhook
DELETE /webhooks/:id/
Deletes a webhook
Request example
curl -X DELETE https://connect.offorte.com/api/v1/{account_name}/webhooks/:id/
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
Update webhook
PATCH /webhooks/:id/
Updates the webhook details with the provided attributes. Other (unprovided) attributes remain unchanged
Request example
curl -X PATCH https://connect.offorte.com/api/v1/{account_name}/webhooks/:id/ \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json; charset=utf-8'
Body
{
"payload_url": "https://example.com/incoming",
"payload_content_type": "json",
"active": true,
"events": [
"company_created"
]
}
Parameters
name | type | description |
---|---|---|
payload_url | string | Url where the data will be posted to; must be a full https url |
payload_content_type | string | Content type header: json |
active | boolean | Is it active or not |
events | array | Events to subscribe to |