Proposify Public API Documentation

If you are interested in integrating with Proposify, contact us at api@proposify.com


Using this documentation


Here are some general guidelines:
  1. Variables are prefixed with a colon. For instance, the URL  GET /api/activity?proposal_id=:proposal_id includes the variable :proposal_id. You will need to pass the contents of this variable in order for the specified call to our API to work.
  2. Always send an Accept header of "application/json" unless specified otherwise.
  3. Always send a Content-Type header of "application/json" when using PUT/POST, unless specified otherwise.
  4. All URLs start with https://api.proposify.com. If you see GET /api/ping, this means that the full URL is https://api.proposify.com/api/ping
  5. All times are ISO 8601 datetimes formatted to the RFC 3339 standard, e.g. 2017-05-30T15:31:51-03:00
  6. For endpoints that return a list of data, 50 results are returned at a time. You must provide an offset of a multiple of 50 when searching for additional pages. ex: GET /api/activity?offset=:offset
  7. Some endpoints allow for keyword searching. ex: GET /api/activity?keywords=:keywords
  8. Only the fields that are included in the PUT request will be modified. If you wish to unset a value, you must send it as part of the request body with either null or an empty string. Note that some fields are required for PUT requests (noted in the descriptions of each call).
  9. Some API endpoints are only accessible to account administrators or to accounts with specific features enabled. To see what features the authenticated user has access to, use the GET /api/user/me/role endpoint (further details provided in the endpoints section).
  10. For endpoints with multiple pages, check the Proposify-Has-More-Results response header to see if there are any pages left.

Authentication

Clients can authenticate with the Proposify API by using the Authorization Code flow of OAuth 2.0. There are many libraries and frameworks with OAuth support built-in. If you need a library for your code, you can find a great list on the OAuth website. Assistance with building a custom OAuth 2.0 library is beyond the scope of this article.

Authorization Code URL (you redirect here): https://api.proposify.com/api/authcode
Access Token URL: https://api.proposify.com/api/authtoken

Additional Information:

  1. Posting requests to the Access Token URL requires a content type of application/x-www-form-urlencoded.
  2. Access tokens expire after 1 hour
  3. When retrieving a new Access Token, we also return a new Refresh Token. Please ensure that you persist this Refresh Token.
  4. The only scope supported for OAuth tokens is "all". This parameter is not required and may be left empty. If you specify any scope other than "all" we will return an error.
  5. We require that all access tokens be included in an Authorization header. The header should have this format:
Authorization: Bearer :access_token

HTTP Status/Error Codes:

All of the following codes contain a response body unless otherwise noted.

Success:
200:
  • Successful GET request
  • Successful PUT request when the request includes a request body
201:
  • Successful POST request
204:
  • Successful DELETE request OR PUT request when the request does not include a request body - does not return a response body

Errors:
400:
  • You have a Content-type header of application/json but we failed to decode the request body
  • Invalid OAuth grant type specified - you may need to troubleshoot your OAuth library
  • Unable to process OAuth due to a missing parameter or invalid parameter
  • You are using an OAuth scope other than "all"
  • You are requesting a new access token but your refresh token is invalid or has been revoked
  • You are trying to approve or reject a proposal but the proposal does not require approval.
  • A miscellaneous unknown error has occurred. Let us know if this happens!
401:
  • Invalid client_id or client_secret in OAuth authentication, or there's otherwise some configuration issue
  • You are trying to use an access token that has expired or has been revoked
403:
  • The authenticated user has been deleted by the account owner.
  • The account that the authenticated user belongs to was on a trial and that trial has expired.
  • The account that the authenticated user belongs to no longer has access to the API.
  • The authenticated user does not have permission to access this resource
  • The authenticated user is trying to change the status of a locked proposal.
  • The authenticated user doesn't have permission to approve or reject a proposal.
404:
  • The resource is not found
  • The action that you are requesting for the resource does not exist
  • You have a typo in your URL (returns Content-Type: text/html)
405:
  • Method not supported by this resource
406:
  • You have an Accept header other than application/json
409:
  • You are trying to add/update a user or person and the email is already in use
  • You are trying to add/update a company and the name is already in use
413:
  • Your request is >10MB
415:
  • Your Content-type header is something other than application/json
418:
  • Coffee is for closers
422:
  • You are missing a required POST field or the required POST field is missing a value
  • You have used an email address that isn't valid
500:
  • A PHP or DB error happened in the backend (not a JSON response)
  • Couldn't create an access token for you because of a server issue (contains a JSON response)
501:
  • You're using a request method other than GET, PUT, POST, DELETE, HEAD, or OPTIONS
502:
  • The action was completed successfully but there was an issue (disclosed in the response body) with one or more third party integrations.
503:
  • We are undergoing maintenance. This occurs rarely.
505:
  • You are using an old version of HTTP.

Endpoints:

Check if user has authenticated successfully
GET /api/ping

{
  "status": true
}
Retrieve account data
GET /api/account

{
  "name": "Proposify",
  "subdomain": "alex",
  "custom_domain": "",
  "address_1": "1668 Barrington Street",
  "address_2": "Suite 500",
  "city": "Halifax",
  "state_id": 7,
  "country_id": 1,
  "zip_code": "B3J 2A2",
  "website_url": "https://www.proposify.biz",
  "default_currency_id": 1,
  "created_datetime": "2017-05-30T15:31:51-03:00",
  "state_name": "Nova Scotia",
  "country_name": "Canada"
}
Get activity feed
Limit 50 per page, allows keyword searching.
GET /api/activity

[
  {
    "id": 5360,
    "user_id": 26283,
    "proposal_id": 2559,
    "person_id": null,
    "created_datetime": "2017-05-30T15:40:39-03:00",
    "name": "proposal_edited",
    "description": "{activity_user_name} edited the proposal {proposal_name}",
    "category": "event",
    "proposal_name": "Web Design",
    "client_name": "John Doe",
    "company_name": "Example Company",
    "activity_user_name": "Alex",
    "avatar": "https://secure.gravatar.com/avatar/a11da5b810909b64ac648342d50a96ad?s=30&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fcomment.png",
    "message": "",
    "duration": 0,
    "formatted_datetime": "5 seconds ago"
  }
...
]
Get activity feed for a specific proposal
Limit 50 per page
GET /api/activity?proposal_id=:proposal_id

[
  {
    "id": 5360,
    "user_id": 26283,
    "proposal_id": 2559,
    "person_id": null,
    "created_datetime": "2017-05-30T15:40:39-03:00",
    "name": "proposal_edited",
    "description": "{activity_user_name} edited the proposal {proposal_name}",
    "category": "event",
    "proposal_name": "Web Design",
    "client_name": "John Doe",
    "company_name": "Example Company",
    "activity_user_name": "Alex",
    "avatar": "https://secure.gravatar.com/avatar/a11da5b810909b64ac648342d50a96ad?s=30&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fcomment.png",
    "message": "",
    "duration": 0,
    "formatted_datetime": "4 minutes ago"
  }
...
]
Get details of a specific activity
GET /api/activity/:activity_id

{
  "created_datetime": "2017-05-30T15:40:39-03:00",
  "person_id": null,
  "proposal_id": 2559,
  "name": "proposal_edited",
  "description": "{activity_user_name} edited the proposal {proposal_name}",
  "category": "event",
  "proposal_name": "Web Design",
  "id": 5360,
  "client_name": "John Doe",
  "company_name": "Example Company",
  "activity_user_name": "Alex",
  "user_id": 26283,
  "avatar": "https://secure.gravatar.com/avatar/a11da5b810909b64ac648342d50a96ad?s=30&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fcomment.png",
  "message": "",
  "duration": 0,
  "formatted_datetime": "5 minutes ago"
}
Get the email address associated with an item in the activity feed
Restricted to activities with an activity name of "proposal_sent"
Optional: Use an accept header of
text/html to be returned the HTML of the email
GET /api/activity/:activity_id/email
Accept: application/json

{
  "from": "myproposal@proposify.biz",
  "to": "john@example.com",
  "subject": "Web Design - Proposify",
  "email": "..."
}
Get a comment by ID
Note: You can get the comment ID the associated activity feed item. It will be the "comment_id" field
GET /api/comment/:comment_id

{
  "id": 1078,
  "proposal_id": 2559,
  "message": "Testing",
  "user_id": 26283,
  "internal": 1,
  "created_datetime": "2017-05-30T15:56:13-03:00",
  "first_name": "Alex",
  "activity_user_name": "Alex",
  "last_name": "Plumb",
  "person_id": null,
  "activity_id": 5363,
  "read_status": "read",
  "page_num": -1,
  "trail": [
    {
      "id": 1078,
      "proposal_id": 2559,
      "message": "Testing",
      "user_id": 26283,
      "internal": 1,
      "created_datetime": "2017-05-30T15:56:13-03:00",
      "first_name": "Alex",
      "activity_user_name": "Alex",
      "last_name": "Plumb",
      "person_id": null,
      "read_status": "read"
    }
  ]
}
Delete a specific comment
DELETE /api/comment/:comment_id
Mark a comment as read
PUT /api/comment/:comment_id/read
Reply to an existing comment
Note: Requires message field
POST /api/comment/:comment_id/reply
{
  "message": "Test comment!"
}

{
  "id": 1080,
  "proposal_id": 2559,
  "message": "Test comment!",
  "user_id": 26283,
  "internal": 1,
  "created_datetime": "2017-05-31T10:49:08-03:00",
  "first_name": "Alex",
  "activity_user_name": "Alex",
  "last_name": "Plumb",
  "person_id": null,
  "activity_id": 5371,
  "read_status": "read",
  "page_num": -1
}
List companies in the client list
Limit 50 per page, allows keyword searching.
GET /api/company

[
  {
    "id": 3670,
    "name": "Example Company",
    "website_url": "http://www.timhortons.com",
    "address_1": "123 Fake Street",
    "address_2": "Unit 42",
    "city": "Halifax",
    "state_id": 7,
    "country_id": 1,
    "zip_code": "B2Y4V2",
    "state_name": "Nova Scotia",
    "country_name": "Canada",
    "win_rate": 0,
    "people": [
      {
        "id": 234002,
        "company_id": 3670,
        "first_name": "John",
        "last_name": "Doe",
        "email": "john@example.com",
        "title": "Head Honcho",
        "office_no": "(555) 555-5555",
        "mobile_no": "(111) 111-1111",
        "is_primary": 1,
        "use_company_address": 1,
        "company_name": "Example Company",
        "website_url": "http://www.timhortons.com",
        "address_1": "123 Fake Street",
        "address_2": "Unit 42",
        "city": "Halifax",
        "zip_code": "B2Y4V2",
        "country_id": 1,
        "state_id": 7,
        "state_name": "Nova Scotia",
        "country_name": "Canada",
        "win_rate": 0,
        "avatar": "https://secure.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=30&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png"
      }
      ...
    ]
  }
...
]
Get details of one company
GET /api/company/:company_id

{
  "id": 3672,
  "name": "Propositron",
  "website_url": "https://www.proposify.biz",
  "address_1": "1668 Barrington Street",
  "address_2": "Suite 500",
  "city": "Halifax",
  "state_id": null,
  "country_id": null,
  "zip_code": "B3J 2A2",
  "state_name": null,
  "country_name": null,
  "win_rate": 0,
  "people": []
}
Create a new company
Note: Requires name field
POST /api/company
{
  "name": "Proposify",
  "website_url": "https://www.proposify.biz",
  "address_1": "1668 Barrington Street",
  "address_2": "Suite 500",
  "city": "Halifax",
  "state_id": 7,
  "country_id": 1,
  "zip_code": "B3J 2A2"
}

{
  "id": 3672,
  "name": "Proposify",
  "website_url": "https://www.proposify.biz",
  "address_1": "1668 Barrington Street",
  "address_2": "Suite 500",
  "city": "Halifax",
  "state_id": 7,
  "country_id": 1,
  "zip_code": "B3J 2A2",
  "state_name": "Nova Scotia",
  "country_name": "Canada",
  "win_rate": 0,
  "people": []
}
Update an existing company
Note: Requires name field
PUT /api/company/:company_id
{
  "name": "Propositron",
  "website_url": "https://www.proposify.biz"
}

{
  "id": 3672,
  "name": "Propositron",
  "website_url": "https://www.proposify.biz",
  "address_1": "1668 Barrington Street",
  "address_2": "Suite 500",
  "city": "Halifax",
  "state_id": null,
  "country_id": null,
  "zip_code": "B3J 2A2",
  "state_name": null,
  "country_name": null,
  "win_rate": 0,
  "people": []
}
Delete a company
DELETE /api/company
Get non-archived proposals associated with a company
Limit 50 per page, allows keyword searching
GET /api/company/:company_id/proposal

[
  {
    "id": 2559,
    "person_id": 234002,
    "user_id": 26283,
    "name": "Web Design",
    "number": 1,
    "due_date": "2017-05-31T00:00:00-03:00",
    "value": 1060.2,
    "archive": 0,
    "approved_user_id": null,
    "approved_datetime": null,
    "status_name": "Sent",
    "client_name": "Example Company",
    "currency_code": "USD",
    "preview_url": "https://alex.proposify.biz/preview/UNbbbbbbbc",
    "formatted_value": "$1,060.20",
    "restricted": false
  }
...
]
Get a list of all countries
GET /api/country

[
  {
    "id": 5,
    "name": "Afghanistan",
    "abbreviation": "AFG",
    "code": "AF"
  },
  {
    "id": 240,
    "name": "Aland Islands",
    "abbreviation": "ALA",
    "code": "AX"
  },
...
]
Get a list of all currencies
Note: You can get a list of only the currencies being used by this account by using the query string ?used=true
GET /api/currency

[
  {
    "id": 57,
    "name": "Afghani",
    "currency": "Afs",
    "code": "AFN"
  },
  {
    "id": 77,
    "name": "Algerian Dinar",
    "currency": "DZD",
    "code": "DZD"
  },
...
]
Get a list of all possible activity feed event types
GET /api/event

[
  {
    "id": 1,
    "name": "proposal_created",
    "description": "{activity_user_name} created the proposal {proposal_name}",
    "category": "event"
  },
  {
    "id": 2,
    "name": "proposal_sent",
    "description": "{activity_user_name} sent the proposal {proposal_name}",
    "category": "event"
  },
  {
    "id": 3,
    "name": "proposal_edited",
    "description": "{activity_user_name} edited the proposal {proposal_name}",
    "category": "event"
  },
...
]
List people in the client list
Limit 50 per page, allows keyword searching.
GET /api/person

[
  {
    "id": 234002,
    "company_id": 3670,
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com",
    "title": "Head Honcho",
    "office_no": "(555) 555-5555",
    "mobile_no": "(111) 111-1111",
    "is_primary": 1,
    "use_company_address": 1,
    "company_name": "Example Company",
    "website_url": "http://www.timhortons.com",
    "address_1": "123 Fake Street",
    "address_2": "Unit 42",
    "city": "Halifax",
    "zip_code": "B2Y4V2",
    "country_id": 1,
    "state_id": 7,
    "state_name": "Nova Scotia",
    "country_name": "Canada"
  }
...
]
Get details of one person
GET /api/person/:person_id

{
  "id": 234002,
  "company_id": 3670,
  "first_name": "John",
  "last_name": "Doe",
  "email": "john@example.com",
  "title": "Head Honcho",
  "office_no": "(555) 555-5555",
  "mobile_no": "(111) 111-1111",
  "is_primary": 0,
  "use_company_address": 1,
  "company_name": "Example Company",
  "website_url": "http://www.timhortons.com",
  "address_1": "123 Fake Street",
  "address_2": "Unit 42",
  "city": "Halifax",
  "zip_code": "B2Y4V2",
  "country_id": 1,
  "state_id": 7,
  "state_name": "Nova Scotia",
  "country_name": "Canada",
  "win_rate": 0,
  "avatar": "https://secure.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=30&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png"
}
Create a new person
Note: Requires first_name, last_name, and email fields
POST /api/person
{
  "company_id": 3670,
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane@test.com",
  "title": "CEO",
  "office_no": "(555) 555-5555",
  "mobile_no": "(111) 111-1111",
  "is_primary": 1,
  "use_company_address": 0,
  "website_url": "http://www.timhortons.com",
  "address_1": "123 Fake Street",
  "address_2": "Unit 42",
  "city": "Halifax",
  "zip_code": "B2Y4V2",
  "country_id": 1,
  "state_id": 7
}

{
  "id": 234004,
  "company_id": 3670,
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane@test.com",
  "title": "CEO",
  "office_no": "(555) 555-5555",
  "mobile_no": "(111) 111-1111",
  "is_primary": 1,
  "use_company_address": 0,
  "company_name": "Example Company",
  "website_url": "http://www.timhortons.com",
  "address_1": "123 Fake Street",
  "address_2": "Unit 42",
  "city": "Halifax",
  "zip_code": "B2Y4V2",
  "country_id": 1,
  "state_id": 7,
  "state_name": "Nova Scotia",
  "country_name": "Canada",
  "win_rate": 0,
  "avatar": "https://secure.gravatar.com/avatar/550cf97cea5f2ce1f7f6a5b06c1c51a8?s=30&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png"
}
Update an existing person
Note: Requires first_name, last_name, and email fields. 
PUT /api/person/:person_id
{
  "first_name": "Janet",
  "last_name": "Bradshaw",
  "email": "janet@example.com"
}

{
  "id": 234004,
  "company_id": 3670,
  "first_name": "Janet",
  "last_name": "Bradshaw",
  "email": "janet@example.com",
  "title": "CEO",
  "office_no": "(555) 555-5555",
  "mobile_no": "(111) 111-1111",
  "is_primary": 1,
  "use_company_address": 0,
  "company_name": "Example Company",
  "website_url": "",
  "address_1": "",
  "address_2": "",
  "city": "",
  "zip_code": "",
  "country_id": null,
  "state_id": null,
  "state_name": null,
  "country_name": null,
  "win_rate": 0,
  "avatar": "https://secure.gravatar.com/avatar/e2b56f44a93e97ccf87e11d6bca1c6fa?s=30&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png"
}
Delete a person
DELETE /api/person
Get non-archived proposals associated with a person
Limit 50 per page, allows keyword searching
GET /api/person/:person_id/proposal

[
  {
    "id": 2559,
    "person_id": 234002,
    "user_id": 26283,
    "name": "Web Design",
    "number": 1,
    "due_date": "2017-05-31T00:00:00-03:00",
    "value": 1060.2,
    "archive": 0,
    "approved_user_id": null,
    "approved_datetime": null,
    "status_name": "Sent",
    "client_name": "Example Company",
    "currency_code": "USD",
    "preview_url": "https://alex.proposify.biz/preview/UNbbbbbbbc",
    "formatted_value": "$1,060.20",
    "restricted": false
  }
...
]
List proposals
Limit 50 per page, allows keyword searching.
Note: Include ?archive=true to search proposal archives
GET /api/proposal

[
  {
    "id": 2559,
    "person_id": 234002,
    "user_id": 26283,
    "name": "Web Design",
    "number": 1,
    "due_date": "2017-05-31T00:00:00-03:00",
    "value": 1060.2,
    "archive": 0,
    "approved_user_id": null,
    "approved_datetime": null,
    "status_name": "Sent",
    "client_name": "Example Company",
    "currency_code": "USD",
    "preview_url": "https://alex.proposify.biz/preview/UNbbbbbbbc",
    "formatted_value": "$1,060.20",
    "restricted": false,
    "internal_attachments": [],
    "client_attachments": []
  }
...
]
Create new proposal
Note: person_id, user_id, name, and due_date fields required
POST /api/proposal

{
  "person_id": 234002,
  "user_id": 26283,
  "name": "Test Proposal",
  "due_date": "2017-10-31",
  "currency_id": 1,
  "number": 5002,
  "tags":[
  	"test",
  	"big money"
  ],
  "preset_id": 2558
}

{
  "id": 2562,
  "person_id": 234002,
  "user_id": 26283,
  "name": "Test Proposal",
  "number": 5002,
  "due_date": "2017-10-31T00:00:00-03:00",
  "value": 1060.2,
  "approved_user_id": null,
  "approved_datetime": null,
  "archive": 0,
  "created_datetime": "2017-05-31T15:13:36-03:00",
  "view_datetime": null,
  "status_name": "Unsent",
  "client_name": "Example Company",
  "currency_code": "USD",
  "preview_url": "https://alex.proposify.biz/preview/XNbbbbbbbc",
  "preview_pdf_url": "https://alex.proposify.biz/preview/download/XNbbbbbbbc",
  "formatted_value": "$1,060.20",
  "restricted": false,
  "internal_attachments": [],
  "client_attachments": [],
  "tags": [
    "big money",
    "test"
  ]
}
Get a proposal
GET /api/proposal/:proposal_id

{
  "id": 2560,
  "person_id": 234002,
  "user_id": 26283,
  "name": "Test Proposal",
  "number": 5002,
  "due_date": "2017-10-31T00:00:00-03:00",
  "value": 1060.2,
  "approved_user_id": null,
  "approved_datetime": null,
  "archive": 0,
  "created_datetime": "2017-05-31T10:34:04-03:00",
  "view_datetime": "2017-05-31T10:40:46-03:00",
  "status_name": "Sent",
  "client_name": "Example Company",
  "currency_code": "USD",
  "preview_url": "https://alex.proposify.biz/preview/VNbbbbbbbc",
  "preview_pdf_url": "https://alex.proposify.biz/preview/download/VNbbbbbbbc",
  "formatted_value": "$1,060.20",
  "restricted": false,
  "internal_attachments": [
    {
      "id": 5526,
      "label": "ezgif_com-optimize_(4).gif",
      "created_datetime": "2017-05-31T10:39:43-03:00",
      "web_path": "//s3.amazonaws.com/py-development/account/977/files/96f0a4222d567797d2b9a38f8427ca4b.gif"
    },
  ...
  ],
  "client_attachments": [
    {
      "id": 5525,
      "label": "Screen_Shot_2017-05-30_at_9_45_24_AM.png",
      "created_datetime": "2017-05-31T10:39:15-03:00",
      "web_path": "//s3.amazonaws.com/py-development/account/977/files/33c85cf12d166bb63f70004453e7857d.png"
    },
  ],
  "tags": [
    "big money",
    "test"
  ]
}
Update an existing proposal
Note: person_id, user_id, name, and due_date fields required
PUT /api/proposal/:proposal_id
{
  "person_id": 234002,
  "user_id": 26283,
  "name": "Test Proposal",
  "due_date": "2017-10-31",
  "currency_id": 5,
  "tags":[
  	"test",
  	"big money",
  	"tag1",
  	"tag2"
  ]
}

{
  "id": 2560,
  "person_id": 234002,
  "user_id": 26283,
  "name": "Test Proposal",
  "number": 5002,
  "due_date": "2017-10-31T00:00:00-03:00",
  "value": 1060.2,
  "approved_user_id": null,
  "approved_datetime": null,
  "archive": 0,
  "created_datetime": "2017-05-31T10:34:04-03:00",
  "view_datetime": "2017-05-31T10:40:46-03:00",
  "status_name": "Sent",
  "client_name": "Example Company",
  "currency_code": "AUD",
  "preview_url": "https://alex.proposify.biz/preview/VNbbbbbbbc",
  "preview_pdf_url": "https://alex.proposify.biz/preview/download/VNbbbbbbbc",
  "formatted_value": "$1,060.20",
  "restricted": false,
  "internal_attachments": [
    {
      "id": 5526,
      "label": "ezgif_com-optimize_(4).gif",
      "created_datetime": "2017-05-31T10:39:43-03:00",
      "web_path": "//s3.amazonaws.com/py-development/account/977/files/96f0a4222d567797d2b9a38f8427ca4b.gif"
    },
  ...
  ],
  "client_attachments": [
    {
      "id": 5525,
      "label": "Screen_Shot_2017-05-30_at_9_45_24_AM.png",
      "created_datetime": "2017-05-31T10:39:15-03:00",
      "web_path": "//s3.amazonaws.com/py-development/account/977/files/33c85cf12d166bb63f70004453e7857d.png"
    },
  ...
  ],
  "tags": [
    "big money",
    "tag1",
    "tag2",
    "test"
  ]
}
Delete a proposal
DELETE /api/proposal/:proposal_id
Get the current status of a proposal
GET /api/proposal/:proposal_id/status

{
  "status_id": 4,
  "status": "Won"
}
Set the status of a proposal to Draft
PUT /api/proposal/:proposal_id/status/draft
Set the status of a proposal to Sent
PUT /api/proposal/:proposal_id/status/sent
Set the status of a proposal to Won
PUT /api/proposal/:proposal_id/status/won
Set the status of a proposal to Lost
PUT /api/proposal/:proposal_id/status/lost
Get the proposal archive status
GET /api/proposal/:proposal_id/archive

{
  "archive": 1
}
Archive a proposal
PUT /api/proposal/:proposal_id/archive
Get whether or not a proposal has been approved
GET /api/proposal/:proposal_id/approve

{
  "approved": false
}
Approve a proposal
Note: Only works if the proposal requires approval
PUT /api/proposal/:proposal_id/approve
Reject a proposal
Note: Only works if the proposal requires approval
PUT /api/proposal/:proposal_id/reject
Add a note to a proposal
Note: Notes only show up on the proposal activity feed
POST /api/proposal/:proposal_id/comment
{
  "message": "Everything looks great with this proposal."
}

{
  "id": 1082,
  "proposal_id": 2562,
  "message": "Everything looks great with this proposal.",
  "user_id": 26283,
  "internal": 1,
  "created_datetime": "2017-05-31T16:54:27-03:00",
  "first_name": "Alex",
  "activity_user_name": "Alex",
  "last_name": "Plumb",
  "person_id": null,
  "activity_id": 5388,
  "read_status": "read",
  "page_num": -1
}
List all notes for a proposal
Note: Notes only show up on the proposal activity feed
GET /api/proposal/:proposal_id/comment

[
  {
    "id": 1081,
    "proposal_id": 2562,
    "message": "Everything looks great with this proposal.",
    "user_id": 26283,
    "internal": 1,
    "created_datetime": "2017-05-31T16:52:55-03:00",
    "first_name": "Alex",
    "last_name": "Plumb",
    "person_id": null,
    "read_status": "unread"
  },
...
]
List all roles in the account
Note: Requires access to the permissions feature and user must be an administrator
GET /api/role

[
  {
    "id": 41,
    "name": "Test Role",
    "proposal_view": 1,
    "proposal_design": 1,
    "proposal_reminders": 1,
    "proposal_integrations": 1,
    "proposal_sign": 1,
    "proposal_assign": 1,
    "proposal_restore": 1,
    "proposal_delete": 1,
    "proposal_requires_approval": 0,
    "proposal_approver_role_id": null,
    "preview_settings": 1,
    "library_sections": 1,
    "library_images": 1,
    "library_fees": 1,
    "library_snippets": 1,
    "templates_view": 1,
    "templates_edit": 1,
    "metrics_view": 1,
    "users_view": 1,
    "users_edit": 1,
    "clients_view": 1,
    "clients_edit": 1,
    "settings_team": 1,
    "settings_email": 1,
    "settings_fonts": 1,
    "settings_tags": 1,
    "settings_integrations": 1,
    "settings_currency": 1,
    "settings_preview": 1,
    "streams_edit": 1
  },
...
]
Get details of a single role
Note: Requires access to the permissions feature and user must be an administrator
GET /api/role/:role_id

{
  "id": 41,
  "name": "Test Role",
  "proposal_view": 1,
  "proposal_design": 1,
  "proposal_reminders": 1,
  "proposal_integrations": 1,
  "proposal_sign": 1,
  "proposal_assign": 1,
  "proposal_restore": 1,
  "proposal_delete": 1,
  "proposal_requires_approval": 0,
  "proposal_approver_role_id": null,
  "preview_settings": 1,
  "library_sections": 1,
  "library_images": 1,
  "library_fees": 1,
  "library_snippets": 1,
  "templates_view": 1,
  "templates_edit": 1,
  "metrics_view": 1,
  "users_view": 1,
  "users_edit": 1,
  "clients_view": 1,
  "clients_edit": 1,
  "settings_team": 1,
  "settings_email": 1,
  "settings_fonts": 1,
  "settings_tags": 1,
  "settings_integrations": 1,
  "settings_currency": 1,
  "settings_preview": 1,
  "streams_edit": 1
}
Get a list of all provinces, states, territories, etc.
Note: Pass ?country_id=:country_id to list all states in a specific country
GET /api/state

[
  {
    "id": 4463,
    "country_id": 235,
    "name": "'Adan",
    "abbreviation": "AD",
    "country_name": "Yemen",
    "country_abbreviation": "YEM",
    "country_code": "YE"
  },
  {
    "id": 73,
    "country_id": 4,
    "name": "'Ajmān",
    "abbreviation": "AJ",
    "country_name": "United Arab Emirates",
    "country_abbreviation": "ARE",
    "country_code": "AE"
  },
...
]
Get all teams
Note: Requires access to the teams feature and a permission of settings_team = 1
GET /api/team

[
  {
    "id": 40,
    "name": "Test Team",
    "company_name": "Our Company",
    "custom_domain": null,
    "use_custom_address": 1,
    "address_1": "1668 Barrington Street",
    "address_2": "Suite 500",
    "city": "Halifax",
    "state_id": 7,
    "country_id": 1,
    "zip_code": "B3L 2A2",
    "website_url": "https://www.proposify.biz",
    "default_currency_code": "PLN",
    "users": [
      {
        "id": 26283,
        "email": "testapi@proposify.biz",
        "first_name": "Alex",
        "last_name": "Plumb",
        "title": "Developer",
        "phone": "1-800-555-TEST",
        "avatar": "https://secure.gravatar.com/avatar/a11da5b810909b64ac648342d50a96ad?s=120&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png",
        "timezone_id": 113,
        "team_id": 40,
        "role_id": null,
        "created_datetime": "2017-05-30T15:31:52-03:00",
        "user_type_name": "Owner",
        "user_provider_name": "Proposify",
        "timezone": "America/Halifax"
      },
    ...
    ]
  },
...
]
Get details on a specific team
Note: Requires access to the teams feature and a permission of settings_team = 1
GET /api/team/:team_id

{
  "id": 40,
  "name": "Test Team",
  "company_name": "Our Company",
  "custom_domain": null,
  "use_custom_address": 1,
  "address_1": "1668 Barrington Street",
  "address_2": "Suite 500",
  "city": "Halifax",
  "state_id": 7,
  "country_id": 1,
  "zip_code": "B3L 2A2",
  "website_url": "https://www.proposify.biz",
  "default_currency_code": "PLN",
  "users": [
    {
      "id": 26283,
      "email": "testapi@proposify.biz",
      "first_name": "Alex",
      "last_name": "Plumb",
      "title": "Developer",
      "phone": "1-800-555-TEST",
      "avatar": "https://secure.gravatar.com/avatar/a11da5b810909b64ac648342d50a96ad?s=120&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png",
      "timezone_id": 113,
      "team_id": 40,
      "role_id": null,
      "created_datetime": "2017-05-30T15:31:52-03:00",
      "user_type_name": "Owner",
      "user_provider_name": "Proposify",
      "timezone": "America/Halifax"
    },
  ...
  ]
}
List all time zones
GET /api/timezone

[
  {
    "id": 1,
    "name": "Africa/Abidjan",
    "country_id": 43,
    "country_name": "Ivory Coast",
    "country_abbreviation": "CIV",
    "country_code": "CI"
  },
  {
    "id": 2,
    "name": "Africa/Accra",
    "country_id": 80,
    "country_name": "Ghana",
    "country_abbreviation": "GHA",
    "country_code": "GH"
  },
...
]
List all users
GET /api/user

[
  {
    "id": 26283,
    "email": "testapi@proposify.biz",
    "first_name": "Alex",
    "last_name": "Plumb",
    "title": "Developer",
    "phone": "1-800-555-TEST",
    "avatar": "https://secure.gravatar.com/avatar/a11da5b810909b64ac648342d50a96ad?s=120&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png",
    "timezone_id": 113,
    "team_id": 40,
    "role_id": null,
    "created_datetime": "2017-05-30T15:31:52-03:00",
    "user_type_name": "Owner",
    "user_provider_name": "Proposify",
    "timezone": "America/Halifax"
  },
...
]
Get details of the authenticated user
GET /api/user/me

{
  "id": 26283,
  "email": "testapi@proposify.biz",
  "first_name": "Alex",
  "last_name": "Plumb",
  "title": "Developer",
  "phone": "1-800-555-TEST",
  "avatar": "https://secure.gravatar.com/avatar/a11da5b810909b64ac648342d50a96ad?s=120&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png",
  "timezone_id": 113,
  "team_id": 40,
  "role_id": null,
  "created_datetime": "2017-05-30T15:31:52-03:00",
  "user_type_name": "Owner",
  "user_provider_name": "Proposify",
  "timezone": "America/Halifax"
}
Get permissions/role data of the authenticated user
GET /api/user/me/role

{
  "proposal_view": 1,
  "proposal_design": 1,
  "proposal_reminders": 1,
  "proposal_integrations": 1,
  "proposal_sign": 1,
  "proposal_assign": 1,
  "proposal_restore": 1,
  "proposal_delete": 1,
  "proposal_requires_approval": 0,
  "proposal_approver_role_id": null,
  "preview_settings": 1,
  "library_sections": 1,
  "library_images": 1,
  "library_fees": 1,
  "library_snippets": 1,
  "templates_view": 1,
  "templates_edit": 1,
  "metrics_view": 1,
  "users_view": 1,
  "users_edit": 1,
  "clients_view": 1,
  "clients_edit": 1,
  "settings_team": 1,
  "settings_email": 1,
  "settings_fonts": 1,
  "settings_tags": 1,
  "settings_integrations": 1,
  "settings_currency": 1,
  "settings_preview": 1,
  "streams_edit": 1,
  "is_admin": true,
  "has_permissions": true,
  "has_teams": true
}
Invite a user to the Proposify account
Note: Requires permissions of users_edit = 1
Note: Requires first_name, last_name, and email fields
POST /api/user
{
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane@example.com",
  "title": "CFO",
  "phone": "1-800-555-TEST",
  "team_id": 40,
  "role_id": 41,
  "timezone_id": 113
}

{
  "id": 26284,
  "email": "jane@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "title": "CFO",
  "phone": "1-800-555-TEST",
  "avatar": "https://secure.gravatar.com/avatar/9e26471d35a78862c17e467d87cddedf?s=120&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png",
  "timezone_id": 113,
  "team_id": 40,
  "role_id": 41,
  "created_datetime": "2017-06-01T09:46:52-03:00",
  "user_type_name": "Invited",
  "user_provider_name": "Proposify",
  "timezone": "America/Halifax"
}
Update a user
Note: You cannot change the role_id of a user through the API
PUT /api/user/:user_id
{
  "first_name": "Jane",
  "last_name": "Doe",
  "email": "jane@example.com",
  "title": "Head Honcho"
}

{
  "id": 26284,
  "email": "jane@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "title": "Head Honcho",
  "phone": "1-800-555-TEST",
  "avatar": "https://secure.gravatar.com/avatar/9e26471d35a78862c17e467d87cddedf?s=120&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png",
  "timezone_id": 113,
  "team_id": 40,
  "role_id": 41,
  "created_datetime": "2017-06-01T09:46:52-03:00",
  "user_type_name": "Invited",
  "user_provider_name": "Proposify",
  "timezone": "America/Halifax"
}
Get details of a user
GET /api/user/:user_id

{
  "id": 26284,
  "email": "jane@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "title": "Head Honcho",
  "phone": "1-800-555-TEST",
  "avatar": "https://secure.gravatar.com/avatar/9e26471d35a78862c17e467d87cddedf?s=120&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png",
  "timezone_id": 113,
  "team_id": 40,
  "role_id": 41,
  "created_datetime": "2017-06-01T09:46:52-03:00",
  "user_type_name": "Invited",
  "user_provider_name": "Proposify",
  "timezone": "America/Halifax"
}
Get the role/permissions data of a user
GET /api/user/:user_id/role

{
  "proposal_view": 1,
  "proposal_design": 1,
  "proposal_reminders": 1,
  "proposal_integrations": 1,
  "proposal_sign": 1,
  "proposal_assign": 1,
  "proposal_restore": 1,
  "proposal_delete": 1,
  "proposal_requires_approval": 0,
  "proposal_approver_role_id": null,
  "preview_settings": 1,
  "library_sections": 1,
  "library_images": 1,
  "library_fees": 1,
  "library_snippets": 1,
  "templates_view": 1,
  "templates_edit": 1,
  "metrics_view": 1,
  "users_view": 1,
  "users_edit": 1,
  "clients_view": 1,
  "clients_edit": 1,
  "settings_team": 1,
  "settings_email": 1,
  "settings_fonts": 1,
  "settings_tags": 1,
  "settings_integrations": 1,
  "settings_currency": 1,
  "settings_preview": 1,
  "streams_edit": 1,
  "is_admin": false,
  "has_permissions": true,
  "has_teams": true
}
Delete a user
DELETE /api/user/:user_id
Update current authenticated user
PUT /api/user/me
{
  "first_name": "Alex",
  "last_name": "Plumb",
  "email": "testapi@proposify.biz",
  "team_id": null,
  "timezone_id": 40
}

{
  "id": 26283,
  "email": "testapi@proposify.biz",
  "first_name": "Alex",
  "last_name": "Plumb",
  "title": "Developer",
  "phone": "1-800-555-TEST",
  "avatar": "https://secure.gravatar.com/avatar/a11da5b810909b64ac648342d50a96ad?s=120&d=https%3A%2F%2Fdev.proposify.biz%2Fassets%2Fimages%2Fuser-hq.png",
  "timezone_id": 40,
  "team_id": null,
  "role_id": null,
  "created_datetime": "2017-05-30T15:31:52-03:00",
  "user_type_name": "Owner",
  "user_provider_name": "Proposify",
  "timezone": "Africa/Mbabane"
}

Get all custom fields attached to an object type (proposal, company, person, user)
GET /api/custom_fields/:object_type

[
  {
    "id": "1",
    "field_type_id": "1",
    "field_object_id": "4",
    "name": "Test Custom Field Company",
    "field_object": "company",
    "field_type": "string",
    "value": ""
  }
]

Proposify Data Models


Legend:

I = Integer
S = String
B = Boolean
N = Nullable
D = Datetime (RFC 3339)
F = Float
A = Array
O = Object
U = URI
E = Email Address

Account
name (S) - Name of the account
subdomain (S) - subdomain of the account, e.g. alex.proposify.biz has a subdomain of alex
custom_domain (S,U) - The custom domain on the account, if applicable
address_1 (S)
address_2 (S)
city (S)
state_id (I,N)
state_name (S,N)
country_id (I,N)
country_name (S,N)
zip_code (S)
website_url (S,U)
default_currency_id (I) - The currency used by the account for new proposals
created_datetime (D)

Activity
id (I)
user_id (I,N) - The user that performed the activity, if applicable
proposal_id (I) - The proposal the activity is attached to
proposal_name (S) - The name of the proposal
person_id (I,N) - The client that performed the activity, if applicable
company_id (I,N) - The company of the client that performed the activity, if applicable
client_name (S) - The name of the client
company_name (S) - The name of the company that the client belongs to
created_datetime (D)
name (S) - The name of the event, e.g. proposal_won, internal_comment
description (S) - The text of the event as it appears in the feed
activity_user_name (S) - The name of the user that performed the activity, if applicable
avatar (S) - The avatar of the user, if applicable
comment_id (I) - The comment, if the category is comment
message (S) - The comment message, if the category is comment
page_num (I) - The page number, if the category is comment. Comments made on the proposal snapshot have a page_num of -1
formatted_datetime (S) - The timespan since the activity was made
duration (I) - How long the proposal was viewed for, if activity name = proposal_viewed
category (S) - The category of the event
Possible categories are:
event, comment, attachment, won, lost, system, email, signature
 
Comment
id (I)
proposal_id (I) – ID of the proposal
internal (I) – 1 for team comments and notes, 0 for comments on the client preview
created_datetime (D) – Datetime comment was made
first_name (S) – First name of the user or client
last_name (S) – Last name of the user or client
activity_user_name (S) – Full name of the commenter (“Client” if it’s a client comment)
user_id (I,N) – ID of the user – null if it’s a client comment
person_id (I,N) – ID of the client – null if it’s a user comment
page_num (I) – Page in the document that the comment was made on. -1 for snapshot notes
read_status (S) – read or unread
trail (A) - All other comments within this comment's trail (only accessible from GET /comment/:comment_id endpoint)

Company
id (I)
name (S) – Company name
website_url (S,U) – URL of company website
address_1 (S) – Street address line 1
address_2 (S) – Street address line 2
city (S) - City
state_name (S,N) – Name of state
state_id (I,N) – State ID (per the State model)
country_name (S,N) – Name of country
country_id (I,N) – Country ID (per the Country model)
zip_code (S) – Zip/Postal code
people (A) – A list of People in the company (see the Person model)
win_rate (F) - The close rate for the company
 
Country
id (I)
name (S) – Country name
abbreviation (S) – ISO3166-1 alpha-3
code (S) – ISO3166-1 alpha-2

Currency
id (I)
name (S) - Name of the currency
currency (S) - Currency symbol
code (S) - ISO 4217 currency code
 
Person
id (I)
company_id (I,N) – ID of Company, if applicable (see Company model) – may be null
company_name (S,N) – Name of Company, if applicable
first_name (S) – First name
last_name (S) – Last name
email (S,E) – Email address
title (S) – Job title
office_no (S) – Office phone number
mobile_no (S) – Mobile phone number
is_primary (I) – Whether or not this person is the default contact of the company
use_company_address (I) – If 1, the address fields are for the company.
website_url (S,U)
address_1 (S)
address_2 (S)
city (S)
state_name (S,N)
state_id (I,N)
country_name (S,N)
country_id (I,N)
zip_code (S)
avatar (S) – Avatar or, if no avatar, a link to the gravatar
win_rate (F)
 
Proposal
id (I)
name (S) – Proposal name
person_id (I) – ID of client (see Person model)
client_name (S) – Name of the client (usually name of company, but will be name of Person if no company)
due_date (D) – Date proposal draft is due
number (I) - The proposal number
value (F) – Calculated value of the proposal
formatted_value (S) – Formatted value (with currency settings)
currency_code (S) – ISO 4217 currency code
archive (I) – Archive status
approved_user_id (I,N) – If proposal was approved, by whom
approved_datetime (D,N) – When proposal was approved
status_id (I) – Status ID of proposal 
status_name (S) – One of draft, sent, won, lost, approved, unsigned
viewed_datetime (D,N) – Date proposal was last viewed by a client
internal_attachments (A) – Team attachments (see Attachment model)
client_attachments (A) – Client attachments (see Attachment model)
tags (A) - Proposal tags are represented as an array of strings
preview_url (S,U) - The URL for the client preview of this proposal
preview_pdf_url (S,U) - The URL for the PDF of the proposal
 
Proposal Attachments
id (I)
label (S) – File name
created_datetime (D) – Upload date
web_path (S,U) – URL to the file
 
Role
id (I)
name (S)
proposal_view (I)
proposal_design (I)
proposal_reminders (I)
proposal_integrations (I)
proposal_sign (I)
proposal_assign (I)
proposal_restore (I)
proposal_delete (I)
proposal_requires_approval (I)
proposal_approver_role_id (I,N)
preview_settings (I)
proposal_send_others (I)
library_sections (I)
library_images (I)
library_fees (I)
library_snippets (I)
templates_view (I)
templates_edit (I)
metrics_view (I)
users_view (I)
users_edit (I)
clients_view (I)
clients_edit (I)
settings_team (I)
settings_email (I)
settings_fonts (I)
settings_tags (I)
settings_integrations (I)
settings_currency (I)
settings_preview (I)
 
State
id (I)
country_id (I) – ID of the country this state/province is in
name (S) – State/province name
abbreviation (S) – ISO3166-2 alpha-2 code
 
Team
id (I)
name (S) – Team name
company_name (S,N) – Team name (as it appears on the client preview)
default_currency_code (S,N) – Currency code of the team
custom_domain (S,N) – Team custom domain (if applicable)
use_custom_address (I)
address_1 (S)
address_2 (S)
city (S)
state_id (I,N)
country_id (I,N)
zip_code (S)
website_url (S,U)
users (A) – List of users within the team
 
Timezone
id (I)
name (S) – Timezone name (in tz)
 
User
id (I)
email (S,E) – User email address
first_name (S) – User first name
last_name (S) – User last name
user_type_name (S) – Either “Owner” or “Regular”
title (S) – User title
phone (S) – User phone number
timezone (S) – User timezone name (in tz format)
timezone_id (I) – User timezone id
created_datetime (D) – Date user was added to the system
team_id (I,N) – User team id
role_id (I,N) – User role id 
user_provider_name (S) – Social network provider for the user
avatar (S) – User’s avatar