NAV
cURL Nusii CLI 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.

Nusii CLI

The Nusii CLI is a command-line tool for the Nusii API. It can be used standalone or with AI coding agents like Claude Code, Codex, and others.

It auto-detects piped output and returns JSON, supports --no-input for non-interactive use, and uses structured exit codes for automation.

# Install with Homebrew
brew install nusii/tap/nusii

# Or install from source
go install github.com/nusii/nusii-cli@latest

# Login (saves your key to ~/.config/nusii/config.yaml)
nusii auth login --api-key YOUR_API_KEY

# Check auth status
nusii auth status
# The Nusii CLI is an alternative to using cURL.
# Install: brew install nusii/tap/nusii
# The Nusii CLI is an alternative to the Ruby gem.
# Install: brew install nusii/tap/nusii

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"
nusii auth login --api-key YOUR_API_KEY
require 'nusii-ruby'

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

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

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"
nusii account
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"
nusii clients list
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"
nusii clients get 100
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"
nusii clients create --email "john@doe.com" --name "John" --surname "Doe"
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"
nusii clients update 100 --email "john@doe.com" --name "John Doe"
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"
nusii clients delete 100
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

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"

# Get only accepted 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?status=accepted"

# Get only draft 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?status=draft"
nusii proposals list

# Get only accepted proposals
nusii proposals list --status accepted

# Get only draft proposals
nusii proposals list --status draft
require 'nusii-ruby'

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

# Get all proposals
Nusii::Proposal.list(page: 1)

# Get only accepted proposals
Nusii::Proposal.list(page: 1, status: 'accepted')

# Get only draft proposals
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"
nusii proposals get 100
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"
          }
        ]
      },
      "recipients": {
        "data": [
          {
            "id": "1",
            "type": "recipients"
          }
        ]
      }
    }
  },
  "included": [
    {
      "id": "1",
      "type": "recipients",
      "attributes": {
        "id": 1,
        "name": "Alice",
        "email": "alice@example.com",
        "eligible_to_sign": true,
        "document_sent": false
      }
    }
  ]
}

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"
nusii proposals create --client-id 100 --title "Webdesign yourwebsite.com"
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"
nusii proposals update 100 --title "Webdesign yourwebsite.com"
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"
nusii proposals delete 100
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"
nusii proposals archive 100
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

Send to a single email (legacy):

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"
nusii proposals send 100 --email "your_client@email.com" --subject "Your Proposal"
require 'nusii-ruby'

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

# TODO not implemented yet

Send to multiple recipients:

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 '{
    "subject": "Your Proposal",
    "message": "Please review the attached proposal.",
    "sender_email": "sender@example.com",
    "recipients": [
      { "name": "Alice", "email": "alice@example.com", "eligible_to_sign": true },
      { "name": "Bob", "email": "bob@example.com", "eligible_to_sign": false }
    ]
  }' \
  "https://app.nusii.com/api/v2/proposals/:id/send_proposal"
nusii proposals send 100 \
  --subject "Your Proposal" \
  --message "Please review the attached proposal." \
  --sender-email "sender@example.com" \
  --recipients '[{"name": "Alice", "email": "alice@example.com", "eligible_to_sign": true}, {"name": "Bob", "email": "bob@example.com", "eligible_to_sign": false}]'
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": "sent",
  "sent_at": "2026-03-02T17:27:54.000Z",
  "sender_id": 42,
  "sender_name": "Michael Koper"
}

This will return 200 OK and the current JSON representation.

You can send a proposal to a single email using the email parameter, or to multiple recipients using the recipients array. When recipients is provided, email is ignored. A maximum of 10 recipients can be specified per request.

If neither sender_id nor sender_email is provided, the sender defaults to the account owner.

HTTP Request

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

Attributes

Parameter Mandatory Type Description
email no String Email of the client. Required when recipients is not provided.
recipients no Array Array of recipient objects (see below). When provided, email is ignored. Maximum 10 recipients.
cc no String CC Email recipients. Need to be comma separated if contains multiple emails.
bcc no String BCC Email recipients. 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.

Recipient Object

Parameter Mandatory Type Description
name yes String Recipient's display name
email yes String Recipient's email address
eligible_to_sign no Boolean Whether this recipient can sign the proposal. Default: false

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"
nusii sections list --proposal-id 126
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"
nusii sections get 100
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"
nusii sections create --proposal-id 126 --title "Introduction"
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"
nusii sections update 100 --title "Introduction"
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"
nusii sections delete 100
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

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"
nusii line-items list
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"
nusii line-items list --section-id 100
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"
nusii line-items create --section-id 100 --name "Development Costs"
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"
nusii line-items update 100 --amount 10000
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"
nusii line-items delete 100
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

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"
nusii activities list --proposal-id 100
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"
nusii activities list --proposal-id 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

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"
nusii users list
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

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"
nusii themes list

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

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"
nusii webhooks list
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"
nusii webhooks get 100
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"
nusii webhooks create --target-url "http://example.com" --events "proposal_created,client_created"
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"
nusii webhooks delete 100
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

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" </span>
  -H "Authorization: Token token=your_access_token"
nusii proposals list --page 2 --per-page 10
{
  "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

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.

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.
422 Unprocessable Entity -- The request was well-formed but could not be processed due to validation errors.
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.