API Documentation

API Endpoint

Salaries

Salaries

For more details on salaries (also called cost rates) please refer to the help article.

The cost rate object represents invidual’s cost rate defined for a certain period of time. A person can have multiple cost rates, however they cannot overlap in time. Cost rates can be defined for various period of times, such as hourly, monthly, etc. Note that different periods affect overheads differently (see the help article).

For defining persons’ cost rates specific to deals and budgets, please refer to deal cost rates.

Please note that we rate limit PATCH and POST api requests for editing salaries to 30 requests per two minutes.

Supported attributes

  • cost (money)

  • currency (string)

  • ended_on (date)

  • holiday_calendar_id (integer)

  • hours (decimal)

  • note (text)

  • overhead (boolean)

  • person_id (integer)

  • salary_type_id (integer)

  • started_on (date)

  • working_hours (json)

  • alternating_hours (boolean)

All money attributes in Productive are integers defined in cents, e.g. 100.42 corresponds to 10042 cents that should be written to cost attribute. currency is a three letter abbreviation, e.g. EUR for Euro and GBP for British Pound.

Enumeration salary_type_id defines cost rate’s time periods which can be:

  • 1 (monthly)

  • 2 (hourly)

  • 3 (weekly)

  • 4 (bi-weekly)

  • 5 (annually)

To define working_hours a valid JSON array is required, such as:

[8, 8, 8, 8, 8, 0, 0, 8, 8, 8, 8, 8, 0, 0]

This array has to contain exactly 14 numbers that represent how many hours the person is expected to work for on each day of the week. Numbers can be integers or decimals. The first seven numbers represent a normal week, the last seven numbers an alternative week. If you do not have the alternating working hours setup, then set alternating_hours flag to false and provide identical first and last seven numbers through working_hours array. The first number in the array is Monday, the 7th number is Sunday. Similarly, the 8th number is Monday and the 14th number is Sunday.

When defining alternating working hours, it is required to set alternating_hours flag to true. You can then define how many hours an employee is expected to work in a normal week and how many during an alternative week, e.g.

[8, 8, 8, 8, 8, 0, 0, 8, 8, 8, 8, 0, 0, 0]

A person with the above setup would normally work 8 hours from Monday to Friday in a normal week, and Monday to Thrusday in an alternative week.

Additionally, note that when alternating_hours flag is set to false you are not allowed to send working_hours where first seven numbers do not match the last seven numbers. We enforce this validation and raise an error (first week must match second week) in case you try to do so.

Various validations are enforced to ensure data integrity on this endpoint:

  • holiday_calendar_id is mandatory

  • person_id is mandatory

  • salary_type_id is mandatory

  • cost is mandatory

  • started_on is mandatory unless person_id refers to a placeholder

  • ended_on has to be after started_on, however it is not mandatory

  • currency is mandatory

  • working_hours is mandatory

Supported filter params

  • person_id (array)

  • after (date)

  • before (date)

Filter operations are supported on this endpoint.

Supported sort params

No sorting is supported on this endpoint. Default sorting is by id, descending.

GET /api/v2/salaries
Requestsreturns salaries

GET  /api/v2/salaries

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Responses200
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "data": [
    {
      "id": "249",
      "type": "salaries",
      "attributes": {
        "default_salary": false,
        "ended_on": "2025-07-02",
        "exchange_date": "2024-08-02",
        "exchange_rate": "1.25",
        "hours": "8.0",
        "note": null,
        "overhead": true,
        "salary_type_id": 2,
        "started_on": "2024-08-02",
        "working_hours": [
          8,
          8,
          8,
          8,
          8,
          0,
          0,
          8,
          8,
          8,
          8,
          8,
          0,
          0
        ],
        "alternating_hours": false,
        "currency": "EUR",
        "currency_default": "USD",
        "currency_normalized": "EUR",
        "cost": 2000,
        "cost_default": 2500,
        "cost_normalized": 2000,
        "hourly_rate": 2000,
        "hourly_rate_default": 2500,
        "hourly_rate_normalized": 2000
      },
      "relationships": {
        "organization": {
          "data": {
            "type": "organizations",
            "id": "1834"
          }
        },
        "person": {
          "meta": {
            "included": false
          }
        },
        "holiday_calendar": {
          "meta": {
            "included": false
          }
        }
      }
    }
  ],
  "links": {
    "first": "http://api-test.productive.io/api/v2/salaries?page%5Bnumber%5D=1&page%5Bsize%5D=30",
    "last": "http://api-test.productive.io/api/v2/salaries?page%5Bnumber%5D=1&page%5Bsize%5D=30"
  },
  "meta": {
    "current_page": 1,
    "total_pages": 1,
    "total_count": 1,
    "page_size": 30,
    "max_page_size": 200
  }
}

Get salaries
GET/api/v2/salaries


GET /api/v2/salaries/1
Requestsreturns salary

GET  /api/v2/salaries/250

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Responses200
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "data": {
    "id": "250",
    "type": "salaries",
    "attributes": {
      "default_salary": false,
      "ended_on": "2025-07-02",
      "exchange_date": "2024-08-02",
      "exchange_rate": "1.25",
      "hours": "8.0",
      "note": null,
      "overhead": true,
      "salary_type_id": 2,
      "started_on": "2024-08-02",
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "alternating_hours": false,
      "currency": "EUR",
      "currency_default": "USD",
      "currency_normalized": "EUR",
      "cost": 2000,
      "cost_default": 2500,
      "cost_normalized": 2000,
      "hourly_rate": 2000,
      "hourly_rate_default": 2500,
      "hourly_rate_normalized": 2000
    },
    "relationships": {
      "organization": {
        "data": {
          "type": "organizations",
          "id": "1835"
        }
      },
      "person": {
        "meta": {
          "included": false
        }
      },
      "holiday_calendar": {
        "meta": {
          "included": false
        }
      }
    }
  },
  "meta": {}
}

Gets a salary
GET/api/v2/salaries/{id}

URI Parameters
HideShow
id
number (required) Example: 1

salary id


POST /api/v2/salaries
Requestscreates salarycreates salarycreates salaryreturns errordoes not create salarycreates salary with overhead: truecreates salary

POST  /api/v2/salaries

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "started_on": "2025-08-02",
      "salary_type_id": 2,
      "currency": "EUR",
      "cost": 2000,
      "hours": 8,
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "holiday_calendar_id": 269
    },
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7459"
        }
      }
    }
  }
}
Responses201
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "data": {
    "id": "252",
    "type": "salaries",
    "attributes": {
      "default_salary": false,
      "ended_on": null,
      "exchange_date": "2025-08-02",
      "exchange_rate": "1.25",
      "hours": "8.0",
      "note": null,
      "overhead": true,
      "salary_type_id": 2,
      "started_on": "2025-08-02",
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "alternating_hours": false,
      "currency": "EUR",
      "currency_default": "USD",
      "currency_normalized": "EUR",
      "cost": 2000,
      "cost_default": 2500,
      "cost_normalized": 2000,
      "hourly_rate": 2000,
      "hourly_rate_default": 2500,
      "hourly_rate_normalized": 2000
    },
    "relationships": {
      "organization": {
        "data": {
          "type": "organizations",
          "id": "1836"
        }
      },
      "person": {
        "meta": {
          "included": false
        }
      },
      "holiday_calendar": {
        "meta": {
          "included": false
        }
      }
    }
  },
  "meta": {}
}

POST  /api/v2/salaries

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "salary_type_id": 2,
      "currency": "EUR",
      "cost": 2000,
      "hours": 8,
      "working_hours": [
        8,
        8,
        8,
        6,
        4,
        2,
        0,
        8,
        8,
        8,
        6,
        4,
        2,
        0
      ],
      "holiday_calendar_id": 271
    },
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7461"
        }
      }
    }
  }
}
Responses201
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "data": {
    "id": "253",
    "type": "salaries",
    "attributes": {
      "default_salary": false,
      "ended_on": null,
      "exchange_date": "2024-08-02",
      "exchange_rate": "1.25",
      "hours": "8.0",
      "note": null,
      "overhead": true,
      "salary_type_id": 2,
      "started_on": "2024-08-02",
      "working_hours": [
        8,
        8,
        8,
        6,
        4,
        2,
        0,
        8,
        8,
        8,
        6,
        4,
        2,
        0
      ],
      "alternating_hours": false,
      "currency": "EUR",
      "currency_default": "USD",
      "currency_normalized": "EUR",
      "cost": 2000,
      "cost_default": 2500,
      "cost_normalized": 2000,
      "hourly_rate": 2000,
      "hourly_rate_default": 2500,
      "hourly_rate_normalized": 2000
    },
    "relationships": {
      "organization": {
        "data": {
          "type": "organizations",
          "id": "1837"
        }
      },
      "person": {
        "meta": {
          "included": false
        }
      },
      "holiday_calendar": {
        "meta": {
          "included": false
        }
      }
    }
  },
  "meta": {}
}

POST  /api/v2/salaries

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "salary_type_id": 2,
      "currency": "EUR",
      "cost": 2000,
      "hours": 8,
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "holiday_calendar_id": 273
    },
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7463"
        }
      }
    }
  }
}
Responses201
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "data": {
    "id": "254",
    "type": "salaries",
    "attributes": {
      "default_salary": false,
      "ended_on": null,
      "exchange_date": "2024-08-02",
      "exchange_rate": "1.25",
      "hours": "8.0",
      "note": null,
      "overhead": true,
      "salary_type_id": 2,
      "started_on": "2024-08-02",
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "alternating_hours": false,
      "currency": "EUR",
      "currency_default": "USD",
      "currency_normalized": "EUR",
      "cost": 2000,
      "cost_default": 2500,
      "cost_normalized": 2000,
      "hourly_rate": 2000,
      "hourly_rate_default": 2500,
      "hourly_rate_normalized": 2000
    },
    "relationships": {
      "organization": {
        "data": {
          "type": "organizations",
          "id": "1838"
        }
      },
      "person": {
        "meta": {
          "included": false
        }
      },
      "holiday_calendar": {
        "meta": {
          "included": false
        }
      }
    }
  },
  "meta": {}
}

POST  /api/v2/salaries

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {},
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7465"
        }
      }
    }
  }
}
Responses422
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "errors": [
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "can't be blank",
      "source": {
        "pointer": "data/attributes/salary_type_id"
      }
    },
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "can't be blank",
      "source": {
        "pointer": "data/attributes/started_on"
      }
    },
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "is not a date",
      "source": {
        "pointer": "data/attributes/started_on"
      }
    },
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "can't be blank",
      "source": {
        "pointer": "data/attributes/currency"
      }
    },
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "is not an valid currency",
      "source": {
        "pointer": "data/attributes/currency"
      }
    },
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "can't be blank",
      "source": {
        "pointer": "data/attributes/working_hours"
      }
    },
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "must contain exactly 14 numbers",
      "source": {
        "pointer": "data/attributes/working_hours"
      }
    }
  ]
}

POST  /api/v2/salaries

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "started_on": "2025-08-02",
      "salary_type_id": 2,
      "hours": "8.0",
      "currency": "EUR",
      "cost": 2000,
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "holiday_calendar_id": 276
    },
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7467"
        }
      }
    }
  }
}
Responses422
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "errors": [
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "attribute is invalid",
      "source": {
        "pointer": "data/attributes/person"
      }
    }
  ]
}

POST  /api/v2/salaries

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "salary_type_id": 2,
      "currency": "EUR",
      "cost": 2000,
      "overhead": true,
      "hours": 8,
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "holiday_calendar_id": 278
    },
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7469"
        }
      }
    }
  }
}
Responses201
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "data": {
    "id": "256",
    "type": "salaries",
    "attributes": {
      "default_salary": false,
      "ended_on": null,
      "exchange_date": "2024-08-02",
      "exchange_rate": "1.25",
      "hours": "8.0",
      "note": null,
      "overhead": true,
      "salary_type_id": 2,
      "started_on": "2024-08-02",
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "alternating_hours": false,
      "currency": "EUR",
      "currency_default": "USD",
      "currency_normalized": "EUR",
      "cost": 2000,
      "cost_default": 2500,
      "cost_normalized": 2000,
      "hourly_rate": 2000,
      "hourly_rate_default": 2500,
      "hourly_rate_normalized": 2000
    },
    "relationships": {
      "organization": {
        "data": {
          "type": "organizations",
          "id": "1841"
        }
      },
      "person": {
        "meta": {
          "included": false
        }
      },
      "holiday_calendar": {
        "meta": {
          "included": false
        }
      }
    }
  },
  "meta": {}
}

POST  /api/v2/salaries

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "salary_type_id": 2,
      "hours": "8.0",
      "currency": "EUR",
      "cost": 2000,
      "overhead": false
    },
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7471"
        }
      }
    }
  }
}
Responses422
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "errors": [
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "attribute is invalid",
      "source": {
        "pointer": "data/attributes/person"
      }
    }
  ]
}

Create a salary
POST/api/v2/salaries

URI Parameters
HideShow
salary_type_id
number (required) Example: 1

salary type id

started_on
date (required) Example: 2018-01-01

started on

currency
string (required) Example: EUR

currency

working_hours
number (required) Example: %5B8%2C+8%2C+8%2C+8%2C+8%2C+0%2C+0%5D

array of 7 integers that represent working hours from monday (first element) to sunday (last element)


PATCH /api/v2/salaries/1
Requestsreturns errorupdates overheaddoes not change attributes

PATCH  /api/v2/salaries/262

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "cost": ""
    }
  }
}
Responses422
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "errors": [
    {
      "status": "422",
      "code": "invalid_attribute",
      "title": "Invalid Attribute",
      "detail": "can't be blank",
      "source": {
        "pointer": "data/attributes/cost"
      }
    }
  ]
}

PATCH  /api/v2/salaries/264

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "overhead": true,
      "holiday_calendar_id": 294
    },
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7486"
        }
      }
    }
  }
}
Responses200
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "data": {
    "id": "264",
    "type": "salaries",
    "attributes": {
      "default_salary": false,
      "ended_on": null,
      "exchange_date": "2024-08-02",
      "exchange_rate": "1.25",
      "hours": "8.0",
      "note": null,
      "overhead": true,
      "salary_type_id": 2,
      "started_on": "2024-08-02",
      "working_hours": [
        8,
        8,
        8,
        8,
        8,
        0,
        0,
        8,
        8,
        8,
        8,
        8,
        0,
        0
      ],
      "alternating_hours": false,
      "currency": "EUR",
      "currency_default": "USD",
      "currency_normalized": "EUR",
      "cost": 2000,
      "cost_default": 2500,
      "cost_normalized": 2000,
      "hourly_rate": 2000,
      "hourly_rate_default": 2500,
      "hourly_rate_normalized": 2000
    },
    "relationships": {
      "organization": {
        "data": {
          "type": "organizations",
          "id": "1849"
        }
      },
      "person": {
        "meta": {
          "included": false
        }
      },
      "holiday_calendar": {
        "meta": {
          "included": false
        }
      }
    }
  },
  "meta": {}
}

PATCH  /api/v2/salaries/265

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Body
{
  "data": {
    "type": "salaries",
    "attributes": {
      "started_on": "2025-08-02",
      "ended_on": "2025-08-02",
      "working_hours": [
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1
      ],
      "holiday_calendar_id": 296
    },
    "relationships": {
      "person": {
        "data": {
          "type": "people",
          "id": "7488"
        }
      }
    }
  }
}
Responses200
Headers
Content-Type: application/vnd.api+json; charset=utf-8
Body
{
  "data": {
    "id": "265",
    "type": "salaries",
    "attributes": {
      "default_salary": false,
      "ended_on": null,
      "exchange_date": "2024-08-02",
      "exchange_rate": "1.25",
      "hours": "8.0",
      "note": null,
      "overhead": false,
      "salary_type_id": 2,
      "started_on": "2024-08-02",
      "working_hours": [
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1,
        1
      ],
      "alternating_hours": false,
      "currency": "EUR",
      "currency_default": "USD",
      "currency_normalized": "EUR",
      "cost": 2000,
      "cost_default": 2500,
      "cost_normalized": 2000,
      "hourly_rate": 2000,
      "hourly_rate_default": 2500,
      "hourly_rate_normalized": 2000
    },
    "relationships": {
      "organization": {
        "data": {
          "type": "organizations",
          "id": "1850"
        }
      },
      "person": {
        "meta": {
          "included": false
        }
      },
      "holiday_calendar": {
        "meta": {
          "included": false
        }
      }
    }
  },
  "meta": {}
}

Update a salary
PATCH/api/v2/salaries/{id}

URI Parameters
HideShow
id
number (required) Example: 1

salary id


DELETE /api/v2/salaries/1
Requestsdeletes salary

DELETE  /api/v2/salaries/266

Headers
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Content-Type: application/vnd.api+json
Responses204
This response has no content.

Deletes a salary
DELETE/api/v2/salaries/{id}

URI Parameters
HideShow
id
number (required) Example: 1

salary id


Generated by aglio on 02 Aug 2025