NAV
cURL Ruby

Introduction

Welcome to the Nusii API! You can use our API to access Nusii API endpoints. All endpoint URLs begin with https://app.nusii.com/api/v2/. All requests must be serialized in JSON and Nusii uses the jsonapi.org specification.

Authentication

We offer a token based authentication. You can find your API access token here. Tokens need to be added in the HTTP_AUTHORIZATION header as Token token=YOUR_API_KEY

# With shell, you can just pass the correct header with each request
curl -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/proposals"

Make sure to replace YOUR_API_KEY with your API key.

Nusii expects the API key to be included in all API requests to the server in a header that looks like the following:

Authorization: Token token=YOUR_API_KEY

Errors

The Nusii API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request could not be understood by the server due to malformed syntax.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The resource requested is hidden and for administrators only.
404 Not Found -- The specified resource could not be found.
405 Method Not Allowed -- You tried to access a resource with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- The resource requested has been removed from our servers.
429 Too Many Requests -- You're requesting too many times.
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.

Rate Limiting

There is a rate limit of 100 API calls every 30 seconds.

With every request to the API we add a couple of headers to the request.

If the rate limit is exceeded you will receive a response HTTP 429 (Too Many Requests).

Header Description
X-Ratelimit-Limit The amount of API calls you can make every 30 seconds (always 100)
X-Ratelimit-Remaining The amount of API calls that are still remaining.
Retry-After The amount of seconds untill it is allowed again to make API calls
X-RateLimit-Reset The timestamp when it is allowed again to make API calls.

Pagination

Some endpoints that return collections are paginated. For these endpoints, the meta object will tell you the current page, count, total number of pages, and total count of the collection.

curl "https://app.nusii.com/api/v2/proposals" \
  -H "Authorization: Token token=your_access_token"
{
  "data": [
    {...},
    {...}
  ],
  "meta": {
    "current-page": 2,
    "next-page": 3,
    "prev-page": 1,
    "total-pages": 4,
    "total-count": 89
  }
}

Query Parameters

Parameter Default Description
page 1 Page number
per 25 Number of results per page

Account

Get my Account

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/account/me"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Account.me

The above command returns JSON structured like this:

{
  "data": {
    "id": "3",
    "type": "accounts",
    "attributes": {
      "email": "hello@your_company.com",
      "name": "Your Company Name",
      "subdomain": "your_company",
      "web": "www.your_company.com",
      "currency": "USD",
      "pdf_page_size": "A4",
      "locale": "en",
      "address": "Your Street Address 50",
      "address_state": "New York",
      "postcode": "10022",
      "city": "New York",
      "telephone": "1234567890",
      "default_theme": "clean"
    }
  }
}

This endpoint retrieves your personal account data.

HTTP Request

GET https://app.nusii.com/api/v2/account/me

Clients

Get all Clients

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/clients"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Client.list(page: 1)

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "12",
      "type": "clients",
      "attributes": {
        "email": "support@nusii.com",
        "name": "Michael",
        "surname": "Koper",
        "full_name": "Michael Koper",
        "currency": "EUR",
        "business": "Michael Koper BV",
        "locale": "nl",
        "pdf_page_size": "A4",
        "web": "www.michaelkoper.com",
        "telephone": "1234567890",
        "address": "Madrid Street 34",
        "city": "Madrid",
        "postcode": "28018",
        "country": "Spain",
        "state": "Madrid"
      }
    }
  ],
  "meta": {
    "current-page": 2,
    "next-page": 3,
    "prev-page": 1,
    "total-pages": 4,
    "total-count": 52
  }
}

This endpoint retrieves all clients.

HTTP Request

GET https://app.nusii.com/api/v2/clients

Get a Client

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/clients/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Client.get(100)

The above command returns JSON structured like this:

{
  "data": {
    "id": "4",
    "type": "clients",
    "attributes": {
      "email": "support@nusii.com",
      "name": "Michael",
      "surname": "Koper",
      "full_name": "Michael Koper",
      "currency": "EUR",
      "business": "Michael Koper BV",
      "locale": "nl",
      "pdf_page_size": "A4",
      "web": "www.michaelkoper.com",
      "telephone": "1234567890",
      "address": "Madrid Street 34",
      "city": "Madrid",
      "postcode": "28018",
      "country": "Spain",
      "state": "Madrid"
    }
  }
}

This endpoint retrieves a single client

HTTP Request

GET https://app.nusii.com/api/v2/clients/:id

Create a client

curl -X POST \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"client": {"email": "john@doe.com", "name": "John", "surname": "Doe", "locale": "en"}}' \
  "https://app.nusii.com/api/v2/clients"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Client.create(
  email: 'john@doe.com',
  name: 'John',
  surname: 'Doe'
)

The above command returns JSON structured like this:

{
  "data": {
    "id": "104",
    "type": "clients",
    "attributes": {
      "email": "john@doe.com",
      "name": "John",
      "surname": "Doe",
      "full_name": "John Doe",
      "currency": "EUR",
      "business": "Michael Koper BV",
      "locale": "en",
      "pdf_page_size": "A4",
      "web": "www.michaelkoper.com",
      "telephone": "1234567890",
      "address": "Madrid Street 34",
      "city": "Madrid",
      "postcode": "28018",
      "country": "Spain",
      "state": "Madrid"
    }
  }
}

This will return 201 Created and the current JSON representation of the client if the creation was a success.

HTTP Request

POST https://app.nusii.com/api/v2/clients

Attributes

Parameter Mandatory Type Description
email yes String Email of the client.
name yes String First name of the client.
surname no String Surname of the client.
currency no String Currency of the client. Default: Account's default currency or USD.
business no String Company name of the client
locale no String Locale of the client. The language of the client's proposal.
pdf_page_size no String The pdf page size of the client's proposal. Default: A4
web no String Website of the client.
telephone no String Telephone number of the client.
address no String Address of the client.
city no String City of the client.
postcode no String Postcode of the client.
country no String Country name of the client
state no String State name of the client.

Update a client

curl -X PUT \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"client": {"email": "john@doe.com", "name": "John Doe"}}' \
  "https://app.nusii.com/api/v2/clients/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

client = Nusii::Client.get(100)

client.email = 'john@doe.com'
client.save

The above command returns JSON structured like this:

{
  "data": {
    "id": "126",
    "type": "proposals",
    "attributes": {
      "email": "support@nusii.com",
      "name": "Michael",
      "surname": "Koper",
      "full_name": "Michael Koper",
      "currency": "EUR",
      "business": "Michael Koper BV",
      "locale": "nl",
      "pdf_page_size": "A4",
      "web": "www.michaelkoper.com",
      "telephone": "1234567890",
      "address": "Madrid Street 34",
      "city": "Madrid",
      "postcode": "28018",
      "country": "Spain",
      "state": "Madrid"
    }
  }
}

This will return 200 OK and the current JSON representation of the client if the creation was a success.

HTTP Request

PUT https://app.nusii.com/api/v2/clients/:id

Attributes

Parameter Mandatory Type Description
email yes String Email of the client.
name yes String First name of the client.
surname no String Surname of the client.
currency no String Currency of the client. Default: Account's default currency or USD.
business no String Company name of the client
locale no String Locale of the client. The language of the client's proposal.
pdf_page_size no String The pdf page size of the client's proposal. Default: A4
web no String Website of the client.
telephone no String Telephone number of the client.
address no String Address of the client.
city no String City of the client.
postcode no String Postcode of the client.
country no String Country name of the client
state no String State name of the client.

Delete a client

curl -X DELETE \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/clients/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

client = Nusii::Client.get(100)
client.destroy

The above command returns JSON structured like this:

{
  "data": {
    "id": "12",
    "type": "clients",
    "attributes": {
      "email": "support@nusii.com",
      "name": "Michael",
      "surname": "Koper",
      "full_name": "Michael Koper",
      "currency": "EUR",
      "business": "Michael Koper BV",
      "locale": "nl",
      "pdf_page_size": "A4",
      "web": "www.michaelkoper.com",
      "telephone": "1234567890",
      "address": "Madrid Street 34",
      "city": "Madrid",
      "postcode": "28018",
      "country": "Spain",
      "state": "Madrid"
    }
  }
}

This endpoint deletes a specific client.

HTTP Request

DELETE https://app.nusii.com/api/v2/clients/:id

Line Items

Get all line items

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/line_items"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::LineItem.list(page: 1)

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "154",
      "type": "line_items",
      "attributes": {
        "section_id": 458,
        "name": "Redesign website",
        "position": 1,
        "cost_type": "fixed",
        "recurring_type": null,
        "per_type": null,
        "quantity": null,
        "updated_at": "2017-11-24T10:30:40.282Z",
        "created_at": "2017-11-24T10:30:40.282Z",
        "currency": "GBP",
        "amount_in_cents": 150000,
        "amount_formatted": "£1,500.00",
        "total_in_cents": 150000,
        "total_formatted": "£1,500.00"
      }
    },
    {...}
  ],
  "meta": {
    "current_page": 1,
    "next_page": 2,
    "prev_page": null,
    "total_pages": 5,
    "total_count": 115
  }
}

This endpoint retrieves all line items.

HTTP Request

GET https://app.nusii.com/api/v2/line_items

Get all line items from section

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/sections/100/line_items"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::LineItem.list(section_id: 100)

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "154",
      "type": "line_items",
      "attributes": {
        "section_id": 458,
        "name": "Redesign website",
        "position": 1,
        "cost_type": "fixed",
        "recurring_type": null,
        "per_type": null,
        "quantity": null,
        "updated_at": "2017-11-24T10:30:40.282Z",
        "created_at": "2017-11-24T10:30:40.282Z",
        "currency": "GBP",
        "amount_in_cents": 150000,
        "amount_formatted": "£1,500.00",
        "total_in_cents": 150000,
        "total_formatted": "£1,500.00"
      }
    },
    {...}
  ]
}

This endpoint retrieves all line items from a given section. This response doesn't support pagination.

HTTP Request

GET https://app.nusii.com/api/v2/sections/100/line_items

Create a line item

curl -X POST \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"line_item": {"name": "Development Costs"}}' \
  "https://app.nusii.com/api/v2/sections/100/line_items"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::LineItem.create(
  section_id: 100, 
  name: 'Development Costs'
)

The above command returns JSON structured like this:

{
  "data": {
    "id": "157",
    "type": "line_items",
    "attributes": {
      "section_id": 458,
      "name": "",
      "position": 2,
      "cost_type": "fixed",
      "recurring_type": null,
      "per_type": null,
      "quantity": null,
      "updated_at": "2017-11-27T10:45:09.919Z",
      "created_at": "2017-11-27T10:45:09.919Z",
      "currency": "GBP",
      "amount_in_cents": null,
      "amount_formatted": "£0.00",
      "total_in_cents": 0,
      "total_formatted": "£0.00"
    }
  }
}

This will return 201 Created and the current JSON representation of the line item if the creation was a success.

HTTP Request

POST https://app.nusii.com/api/v2/sections/100/line_items

Attributes

Parameter Mandatory Type Description
name no Text Body of the line item
cost_type no String Default fixed. Possible values are fixed, recurring or per
recurring_type no String Possible values are yearly, semiannually, trimester, monthly, weekly, daily or hourly
per_type no String Possible values are year, month, week, day, hour, item or unit
position no Integer Position of the line item within the section
quantity no Integer If cost_type is per then total of the line item is calculated by quantity multiplied by amount
amount no Integer Amount in cents

Update a line item

curl -X PUT \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"line_item": {"amount": 10000}}' \
  "https://app.nusii.com/api/v2/line_items/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

line_item = Nusii::LineItem.get(100)

line_item.amount = 10000
line_item.save

The above command returns JSON structured like this:

{
  "data": { 
    "id": "157",
    "type": "line_items",
    "attributes": {
      "section_id": 458,
      "name": "",
      "position": 2,
      "cost_type": "fixed",
      "recurring_type": null,
      "per_type": null,
      "quantity": null,
      "updated_at": "2017-11-27T10:45:09.919Z",
      "created_at": "2017-11-27T10:45:09.919Z",
      "currency": "GBP",
      "amount_in_cents": 10000,
      "amount_formatted": "£100.00",
      "total_in_cents": 10000,
      "total_formatted": "£100.00"
    }

  }
}

This will return 200 OK and the current JSON representation of the line item if the creation was a success.

HTTP Request

PUT https://app.nusii.com/api/v2/line_items/:id

or

PUT https://app.nusii.com/api/v2/sections/458/line_items/:id

Attributes

Parameter Mandatory Type Description
name no Text Body of the line item
cost_type no String Default fixed. Possible values are fixed, recurring or per
recurring_type no String Possible values are yearly, semiannually, trimester, monthly, weekly, daily or hourly
per_type no String Possible values are year, month, week, day, hour, item or unit
position no Integer Position of the line item within the section
quantity no Integer If cost_type is per then total of the line item is calculated by quantity multiplied by amount
amount no Integer Amount in cents

Delete a line item

curl -X DELETE \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/line_items/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

line_item = Nusii::LineItem.get(100)
line_item.destroy

The above command returns JSON structured like this:

{
  "data": { 
    "id": "157",
    "type": "line_items",
    "attributes": {
      "section_id": 458,
      "name": "",
      "position": 2,
      "cost_type": "fixed",
      "recurring_type": null,
      "per_type": null,
      "quantity": null,
      "updated_at": "2017-11-27T10:45:09.919Z",
      "created_at": "2017-11-27T10:45:09.919Z",
      "currency": "GBP",
      "amount_in_cents": 10000,
      "amount_formatted": "£100.00",
      "total_in_cents": 10000,
      "total_formatted": "£100.00"
    }

  }
}

This endpoint deletes a specific line item.

HTTP Request

DELETE https://app.nusii.com/api/v2/line_items/:id

Proposals

Get all Proposals

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/proposals"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Proposal.list(page: 1, status: 'draft', archived: false)

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "126",
      "type": "proposals",
      "attributes": {
        "title": "Webdesign yourwebsite.com",
        "account_id": 3,
        "status": "draft",
        "public_id": "-NqDAkiqpiFLuuw",
        "prepared_by_id": 3,
        "client_id": 5,
        "sender_id": null,
        "currency": "USD"
      },
      "relationships": {
        "sections": {
          "data": [
            {
              "id": "414",
              "type": "sections"
            }
          ]
        }
      }
    }
  ],
  "meta": {
    "current_page": 2,
    "next_page": 3,
    "prev_page": 1,
    "total_pages": 4,
    "total_count": 89
  }
}

This endpoint retrieves all proposals.

HTTP Request

GET https://app.nusii.com/api/v2/proposals

Query Parameters

Parameter Default Description
status null If not set retrieves all proposals, Possible states are draft, pending, accepted, rejected, or clarification
archived false If set to true, the result will only include archived proposals.

Get a proposal

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/proposals/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Proposal.get(100)

The above command returns JSON structured like this:

{
  "data": {
    "id": "126",
    "type": "proposals",
    "attributes": {
      "title": "Webdesign yourwebsite.com",
      "account_id": 3,
      "status": "draft",
      "public_id": "-NqDAkiqpiFLuuw",
      "prepared_by_id": 3,
      "client_id": 5,
      "sender_id": null,
      "currency": "USD"
    },
    "relationships": {
      "sections": {
        "data": [
          {
            "id": "414",
            "type": "sections"
          }
        ]
      }
    }
  }
}

This endpoint retrieves a single proposal

HTTP Request

GET https://app.nusii.com/api/v2/proposals/:id

Create a proposal

curl -X POST \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"proposal": {"client_id": 100, "title": "Webdesign yourwebsite.com"}}' \
  "https://app.nusii.com/api/v2/proposals"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Proposal.create(
  title: 'Webdesign yourwebsite.com',
  client_id: 100
)

The above command returns JSON structured like this:

{
  "data": {
    "id": "126",
    "type": "proposals",
    "attributes": {
      "title": "Webdesign yourwebsite.com",
      "account_id": 3,
      "status": "draft",
      "public_id": "-NqDAkiqpiFLuuw",
      "prepared_by_id": 3,
      "client_id": 5,
      "sender_id": null,
      "currency": "USD"
    },
    "relationships": {
      "sections": {
        "data": [
          {
            "id": "414",
            "type": "sections"
          }
        ]
      }
    }
  }
}

This will return 201 Created and the current JSON representation of the proposal if the creation was a success.

HTTP Request

POST https://app.nusii.com/api/v2/proposals

Attributes

Parameter Mandatory Type Description
title no String Title of the proposal
client_id no ID Client ID
client_email no String Fetches the client associated with that email. It creates a new client if there is no client with that email. This is ignored when client_id is set.
template_id no ID If set, all the sections are copied over from the template
document_section_title no String Title of the documents section. Default: Documents
prepared_by_id no ID Prepared by user
expires_at no DateTime Date the proposal expires
display_date no DateTime By Default the date displayed on the proposal is the sent date. This can be overwritten with the display_date
report no Boolean This turns the proposal into a report. Default: false
exclude_total no Boolean This excludes the total from the proposal. Default: false
exclude_total_in_pdf no Boolean This excludes the total from the proposal. Default: false
theme no String Theme of the proposal. Default: 'clean'

Update a proposal

curl -X PUT \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"title": "Webdesign yourwebsite.com"}' \
  "https://app.nusii.com/api/v2/proposals/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

proposal = Nusii::Proposal.get(100)
proposal.title = 'Webdesign yourwebsite.com'
proposal.save

The above command returns JSON structured like this:

{
  "data": {
    "id": "126",
    "type": "proposals",
    "attributes": {
      "title": "Webdesign yourwebsite.com",
      "account_id": 3,
      "status": "draft",
      "public_id": "-NqDAkiqpiFLuuw",
      "prepared_by_id": 3,
      "client_id": 5,
      "sender_id": null,
      "currency": "USD"
    },
    "relationships": {
      "sections": {
        "data": [
          {
            "id": "414",
            "type": "sections"
          }
        ]
      }
    }
  }
}

This will return 200 OK and the current JSON representation of the proposal if the update was a success.

HTTP Request

PUT https://app.nusii.com/api/v2/proposals/:id

Attributes

Parameter Mandatory Type Description
title no String Title of the proposal
client_id no ID Client ID
client_email no String Fetches the client associated with that email. It creates a new client if there is no client with that email. This is ignored when client_id is set.
document_section_title no String Title of the documents section. Default: Documents
prepared_by_id no ID Prepared by user
expires_at no DateTime Date the proposal expires
display_date no DateTime By Default the date displayed on the proposal is the sent date. This can be overwritten with the display_date
report no Boolean This turns the proposal into a report. Default: false
exclude_total no Boolean This excludes the total from the proposal. Default: false
exclude_total_in_pdf no Boolean This excludes the total from the proposal. Default: false
theme no String Theme of the proposal. Default: 'clean'

Delete a proposal

curl -X DELETE \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/proposals/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

proposal = Nusii::Proposal.get(100)
proposal.destroy

The above command returns JSON structured like this:

{
  "data": {
    "id": "126",
    "type": "proposals",
    "attributes": {
      "title": "Webdesign yourwebsite.com",
      "account_id": 3,
      "status": "draft",
      "public_id": "-NqDAkiqpiFLuuw",
      "prepared_by_id": 3,
      "client_id": 5,
      "sender_id": null,
      "currency": "USD"
    }
  }
}

This endpoint deletes a specific proposal.

HTTP Request

DELETE https://app.nusii.com/api/v2/proposals/:id

Archive a proposal

curl -X PUT \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/proposals/:id/archive"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

# TODO not implemented yet

The above command returns JSON structured like this:

{
  "data": {
    "id": "126",
    "type": "proposals",
    "attributes": {
      "title": "Webdesign yourwebsite.com",
      "account_id": 3,
      "status": "draft",
      "public_id": "-NqDAkiqpiFLuuw",
      "prepared_by_id": 3,
      "client_id": 5,
      "sender_id": null,
      "currency": "USD",
      "archived_at": "2019-01-01T10:00:00.000Z"
    }
  }
}

This endpoint deletes a specific proposal.

HTTP Request

DELETE https://app.nusii.com/api/v2/proposals/:id

Send a proposal

curl -X PUT \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"email": "your_client@email.com", "subject": "Your Proposal"}' \
  "https://app.nusii.com/api/v2/proposals/:id/send_proposal"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

# TODO not implemented yet

The above command returns JSON structured like this:

{
  "status": "pending",
  "sent_at": "2020-11-17T09:18:32.770Z",
  "sent_at_in_ms": 1605604712000,
  "sender_id": null,
  "sender_name": null
}

This will return 200 OK and the current JSON representation.

HTTP Request

PUT https://app.nusii.com/api/v2/proposals/:id/send_proposal

Attributes

Parameter Mandatory Type Description
email yes String Email of the client
cc no String CC Email receipients. Need to be comma separated if contains multiple emails.
bcc no String BCC Email receipients. Need to be comma separated if contains multiple emails.
subject no String Subject of the email
message no String Body of the email
save_email_template no Boolean Overwrite email template. Default: false
sender_id no ID ID of the sender
sender_email no String Fetches the Sender associated with that email. This is ignored when sender_id is set.

Proposal Activities

Get all proposal activities

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/proposal_activities"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

activities = Nusii::ProposalActivity.list(
  page: 1,
  proposal_id: 100
)

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "259",
      "type": "proposal_activities",
      "attributes": {
        "activity_type": "user_send_proposal",
          "ip_address": "127.0.0.1",
          "additional_fields": {
          "to": "john@doe.com",
          "cc": "joh+cc@doe.com",
          "from": "your@email.com",
          "reply_to": "your@email.com",
          "subject": "You've received your proposal!"
        },
        "proposal_title": "Webdevelopment",
        "proposal_created_at": "2017-11-24T10:30:40.113Z",
        "proposal_sent_at": null,
        "proposal_status": "draft",
        "proposal_public_id": "FYp1S4oBLxbNpQ",
        "proposal_expires_at": null,
        "client_name": "John",
        "client_email": "john@doe.com",
        "client_surname": "Doe",
        "client_full_name": "John Doe",
        "client_business": "Company Name",
        "client_telephone": "1234567890",
        "client_locale": "en",
        "client_address": "Street Address",
        "client_postcode": "28017",
        "client_country": "Spain",
        "client_city": "Madrid",
        "client_state": "Madrid",
        "client_web": "example.com"
      }
    },
    {...}
  ],
  "meta": {
    "current_page": 1,
    "next_page": 2,
    "prev_page": null,
    "total_pages": 9,
    "total_count": 206
  }
} 

This endpoint retrieves all proposal activities.

HTTP Request

GET https://app.nusii.com/api/v2/proposal_activities

Query Parameters

Parameter Default Description
proposal_id null Only get activities from a specific proposal
client_id null Only get activities from a specific client

Get a Proposal Activity

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/proposal_activities/44"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

activity = Nusii::ProposalActivity.get(44)

The above command returns JSON structured like this:

{
  "data": {
    "id": "44",
    "type": "proposal_activities",
    "attributes": {
      "activity_type": "user_send_proposal",
      "ip_address": "127.0.0.1",
      "additional_fields": {
        "to": "john@doe.com",
        "cc": "joh+cc@doe.com",
        "from": "your@email.com",
        "reply_to": "your@email.com",
        "subject": "You've received your proposal!",
        "bounce_type": "HardBounce",
        "bounced_email": "john@doe.com",
        "bounce_description": "The server was unable to deliver your message (ex: unknown user, mailbox not found)."
      },
      "proposal_title": "Design for clientwebsite.com",
      "proposal_created_at": "2016-11-28T15:00:58.794Z",
      "proposal_sent_at": "2017-01-12T12:46:33.396Z",
      "proposal_status": "draft",
      "proposal_public_id": "smaBXa7wa1Jv",
      "proposal_expires_at": null,
      "client_name": "John",
      "client_email": "john@doe.com",
      "client_surname": "Doe",
      "client_full_name": "John Doe",
      "client_business": "John Doe's Business",
      "client_telephone": "1234567890",
      "client_locale": "en",
      "client_address": "Street Address 29",
      "client_postcode": "28017",
      "client_country": "Spain",
      "client_city": "Madrid",
      "client_state": "Madrid",
      "client_web": "www.clientwebsite.com"
    }
  }
}

This endpoint retrieves a single proposal activity

HTTP Request

GET https://app.nusii.com/api/v2/proposal_activities/:id

Parameter Type Description
activty_type String Type of activity. Possible values are: client_view_proposal, client_view_pdf, user_create_proposal, user_view_proposal, user_send_proposal, user_manual_change_status_proposal, client_rejected_proposal, client_clarification_proposal, client_accepted_proposal, client_email_bounced, client_email_opened, and api_created_proposal
ip_address String Ip address of the person that does the activity
additional_fields Hash An hash with additional information. Possible values are: to (email address where the proposal is sent), cc (cc email address where proposal is sent), from (email address where proposal is sent from), reply_to (reply to email address), subject (subject of email), message (the body of the email sent, or the reason of a proposal state change), bounce_type (set if email bounced), bounce_description (description why email bounced)
proposal_attributes ... Look at Proposal for information
client_attributes ... Look at Client for information

Sections

Get all sections

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/sections"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Section.list(page: 1)

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "164",
      "type": "sections",
      "attributes": {
        "currency": "GBP",
        "account_id": 3,
        "proposal_id": 124,
        "template_id": null,
        "title": "Introduction",
        "name": null,
        "body": "Lorem ipsum",
        "position": 0,
        "reusable": false,
        "section_type": "cost",
        "created_at": "2017-03-03T12:23:37.686Z",
        "updated_at": "2017-03-03T12:23:45.828Z",
        "page_break": false,
        "optional": false,
        "selected": false,
        "include_total": false,
        "total_in_cents": 50000,
        "total_formatted": "£500.00"
      },
      "relationships": {
        "line_items": {
          "data": [
            {
              "id": "76",
              "type": "line_items"
            }
          ]
        }
      }
    },
    {...}
  ],
  "meta": {
    "current_page": 1,
    "next_page": 2,
    "prev_page": null,
    "total_pages": 2,
    "total_count": 48
  }
}

This endpoint retrieves all sections.

HTTP Request

GET https://app.nusii.com/api/v2/sections

Query Parameters

Parameter Default Description
proposal_id null If set retrieves all sections of the proposal.
template_id null If set retrieves all sections of the template.
include_line_items false If set to true, the result will have all the data of the line items in the "included" parameter.

Get a section

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/sections/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Section.get(100)

The above command returns JSON structured like this:

{
  "data": {
    "id": "164",
    "type": "sections",
    "attributes": {
      "currency": "GBP",
      "account_id": 3,
      "proposal_id": 126,
      "template_id": null,
      "title": "Introduction",
      "name": null,
      "body": "<p>Hello {{ clientFirstName }}</p>",
      "position": 0,
      "reusable": false,
      "section_type": "cost",
      "created_at": "2017-03-03T12:23:37.686Z",
      "updated_at": "2017-03-03T12:23:45.828Z",
      "page_break": false,
      "optional": false,
      "selected": false,
      "include_total": false,
      "total_in_cents": 50000,
      "total_formatted": "£500.00"
    },
    "relationships": {
      "line_items": {
        "data": [
          {
            "id": "76",
            "type": "line_items"
          }
        ]
      }
    }
  }
}

This endpoint retrieves a single section

HTTP Request

GET https://app.nusii.com/api/v2/sections/:id

Create a section

curl -X POST \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"section": {"title": "Introduction"}}' \
  "https://app.nusii.com/api/v2/sections"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::Section.create(
  title: 'Introduction'
)

The above command returns JSON structured like this:

{
  "data": {
    "id": "164",
    "type": "sections",
    "attributes": {
      "currency": "GBP",
      "account_id": 3,
      "proposal_id": 126,
      "template_id": null,
      "title": "Introduction",
      "name": null,
      "body": null,
      "position": 0,
      "reusable": false,
      "section_type": "cost",
      "created_at": "2017-03-03T12:23:37.686Z",
      "updated_at": "2017-03-03T12:23:45.828Z",
      "page_break": false,
      "optional": false,
      "selected": false,
      "include_total": false,
      "total_in_cents": 50000,
      "total_formatted": "£500.00"
    },
    "relationships": {
      "line_items": {
        "data": [
          {
            "id": "76",
            "type": "line_items"
          }
        ]
      }
    }
  }
}

This will return 201 Created and the current JSON representation of the section if the creation was a success.

HTTP Request

POST https://app.nusii.com/api/v2/sections

Attributes

Parameter Mandatory Type Description
proposal_id no ID ID of the proposal
template_id no ID ID of the template
title no String Title of the section
body no Text Body of the section
name no String Internal name of the section
position no Integer Position in the proposal or template.
reusable no Boolean Default false. Reusable sections can be reused to any template / proposal you want.
section_type no String Default text. Can be text or cost. A text section is just a section with a body. A cost section can have line items and has a total.
page_break no Boolean Default false. PDF page break
optional no Boolean Default false. Client can choose the price package when true. Price is fixed when false
include_total no Boolean Default false. Include a subtotal within the section. Not just the end of the proposal.

Update a section

curl -X PUT \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  -d '{"section": {"title": "Introduction"}}' \
  "https://app.nusii.com/api/v2/sections/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

section = Nusii::Section.get(100)
section.title = 'Introduction'
section.save

The above command returns JSON structured like this:

{
  "data": {
    "id": "126",
    "type": "sections",
    "attributes": {
      "currency": "GBP",
      "account_id": 3,
      "proposal_id": 126,
      "template_id": null,
      "title": "Introduction",
      "name": null,
      "body": null,
      "position": 0,
      "reusable": false,
      "section_type": "cost",
      "created_at": "2017-03-03T12:23:37.686Z",
      "updated_at": "2017-03-03T12:23:45.828Z",
      "page_break": false,
      "optional": false,
      "selected": false,
      "include_total": false,
      "total_in_cents": 50000,
      "total_formatted": "£500.00"
    }
  }
}

This will return 200 OK and the current JSON representation of the section if the update was a success.

HTTP Request

PUT https://app.nusii.com/api/v2/sections/:id

Attributes

Parameter Mandatory Type Description
proposal_id no ID ID of the proposal
template_id no ID ID of the template
title no String Title of the section
body no Text Body of the section
name no String Internal name of the section
position no Integer Position in the proposal or template.
reusable no Boolean Default false. Reusable sections can be reused to any template / proposal you want.
section_type no String Default text. Can be text or cost. A text section is just a section with a body. A cost section can have line items and has a total.
page_break no Boolean Default false. PDF page break
optional no Boolean Default false. Client can choose the price package when true. Price is fixed when false
include_total no Boolean Default false. Include a subtotal within the section. Not just the end of the proposal.

Delete a section

curl -X DELETE \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/sections/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

section = Nusii::Section.get(100)
section.destroy

The above command returns JSON structured like this:

{
  "data": {
    "id": "164",
    "type": "sections",
    "attributes": {
      "currency": "GBP",
      "account_id": 3,
      "proposal_id": 126,
      "template_id": null,
      "title": "Introduction",
      "name": null,
      "body": null,
      "position": 0,
      "reusable": false,
      "section_type": "cost",
      "created_at": "2017-03-03T12:23:37.686Z",
      "updated_at": "2017-03-03T12:23:45.828Z",
      "page_break": false,
      "optional": false,
      "selected": false,
      "include_total": false,
      "total_in_cents": 50000,
      "total_formatted": "£500.00"
    }
  }
}

This endpoint deletes a specific section.

HTTP Request

DELETE https://app.nusii.com/api/v2/sections/:id

Themes

Get all Themes

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/themes"

The above command returns JSON structured like this:

  {
    "id": "clean",
    "name": "Modern Theme"
  }, {
    "id": "classic",
    "name": "Classic Theme"
  }
}

This endpoint retrieves all available themes.

HTTP Request

GET https://app.nusii.com/api/v2/themes

Users

Get all Users

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/users"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::User.list(page: 1)

The above command returns JSON structured like this:

  "data": [
    {
      "id": "12",
      "type": "users",
      "attributes": {
        "email": "support@nusii.com",
        "name": "Michael",
      }
    }
  ],
  "meta": {
    "current-page": 2,
    "next-page": 3,
    "prev-page": 1,
    "total-pages": 4,
    "total-count": 52
  }
}

This endpoint retrieves all users.

HTTP Request

GET https://app.nusii.com/api/v2/users

Webhooks

With Nusii webhooks we can send your application requests when something interesting happens, like Proposal Accepted, Proposal Viewed etc.

Webhook endpoint format

Every webhook uses the same structure. It will always be in a standard POST request with the object in the body.

The target url needs to be able to accept Content Type: application/json and POST requests. Everything other than a 2xx request will be concidered an error and we will try will retry 25 times. If we receive a 410 GONE response, we will delete the webhook entirely.

Parameter Description
event_name The name of the event. proposal_created, client_updated etc.
The object An hash that represents the object. The key is always the name of the object. "proposal", "client" etc
  {
    "event_name": "proposal_created",
    "proposal": {
      "id": 30,
      "title": "Webdevelopment",
      ...
    }
  }

Webhook endpoint errors

We concider all responses with 2xx as successful. Other than that we concider it as an error and we will retry the request 24 times. If we receive a 410 GONE, the enpoint will get removed from our database.

Available webhooks

Event Description
proposal_created Sends when a proposal is created
proposal_updated Sends when a proposal is updated
proposal_destroyed Sends when a proposal is deleted
proposal_accepted Sends when a proposal is accepted
proposal_rejected Sends when a proposal is rejected
proposal_sent Sends when a proposal is sent
proposal_activity_client_viewed_proposal Sends when your client views a proposal
client_created Sends when client is created
client_updated Sends when client is updated
client_destroyed Sends when client is deleted

Get all webhook endpoints

curl -X GET \
  -H 'User-Agent: Your App Name (www.yourapp.com)' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Token token=YOUR_API_KEY" \
  "https://app.nusii.com/api/v2/webhook_endpoints"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY'
Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::WebhookEndpoint.list(page: 1)

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": "26",
      "type": "webhook_endpoints",
      "attributes": {
        "events": [
          "proposal_created",
          "client_updated"
        ], "target_url": "http://example.com/webhooks"
      },
    },
    {...}
  ],
  "meta": {
    "current-page": 2,
    "next-page": 3,
    "prev-page": 1,
    "total-pages": 4,
    "total-count": 89
  }
}

This endpoint retrieves all webhooks endpoints.

HTTP Request

GET https://app.nusii.com/api/v2/webhook_endpoints

Get a webhook endpoint

curl -X GET </span>
  -H 'User-Agent: Your App Name (www.yourapp.com)' </span>
  -H 'Content-Type: application/json' </span>
  -H "Authorization: Token token=YOUR_API_KEY" </span>
  "https://app.nusii.com/api/v2/webhook_endpoints/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY' Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::WebhookEndpoint.get(100)

The above command returns JSON structured like this:

{
  "data": {
    "id": "33",
    "type": "webhook_endpoints",
    "attributes": {
      "events": [
        "proposal_created",
        "client_created"
      ],
      "target_url": "http://example.com/webhooks"
    }
  }
}

This endpoint retrieves a single webhook endpoint

HTTP Request

GET https://app.nusii.com/api/v2/webhook_endpoints/:id

Create a webhook endpoint

curl -X POST </span>
  -H 'User-Agent: Your App Name (www.yourapp.com)' </span>
  -H 'Content-Type: application/json' </span>
  -H "Authorization: Token token=YOUR_API_KEY" </span>
  -d '{"webhook_endpoint":{"target_url": "http://example.com","events": ["proposal_created", "client_created"]}}' </span>
  "https://app.nusii.com/api/v2/webhook_endpoints"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY' Nusii.user_agent = 'Your App Name (www.yourapp.com)'

Nusii::WebhookEndpoint.create( target_url: http://example.com, events: ['proposal_created', 'client_created'] )

The above command returns JSON structured like this:

{
  "data": {
    "id": "34",
    "type": "webhook_endpoints",
    "attributes": {
      "events": [
        "proposal_created",
        "client_created"
      ],
      "target_url": "http://example.com"
    }
  }
}

This will return 201 Created and the current JSON representation of the webhook endpoint if the creation was a success.

HTTP Request

POST https://app.nusii.com/api/v2/webhook_endpoints

Attributes

Parameter Mandatory Type Description
target_url yes String Destination url of the webhook request.
events yes String[] An Array of string that represents the events you want to subscribe to.

Delete a webhook endpoint

curl -X DELETE </span>
  -H 'User-Agent: Your App Name (www.yourapp.com)' </span>
  -H 'Content-Type: application/json' </span>
  -H "Authorization: Token token=YOUR_API_KEY" </span>
  "https://app.nusii.com/api/v2/webhook_endpoints/:id"
require 'nusii-ruby'

Nusii.api_key = 'YOUR_API_KEY' Nusii.user_agent = 'Your App Name (www.yourapp.com)'

endpoint = Nusii::WebhookEndpoint.get(100) endpoint.destroy

The above command returns JSON structured like this:

{
  "data": {
    "id": "34",
    "type": "webhook_endpoints",
    "attributes": {
      "events": [
        "proposal_created",
        "client_created"
      ],
      "target_url": "http://example.com"
    }
  }
}

This endpoint deletes a specific webhook_endpoint.

HTTP Request

DELETE https://app.nusii.com/api/v2/webhook_endpoints/:id