curl --request POST \
--url https://www.ruddr.io/api/workspace/project-expenses \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"date": "2023-12-25",
"amount": 123,
"projectId": "<string>",
"expenseCategoryId": "<string>",
"isBillable": true,
"vendor": "<string>",
"notes": "<string>",
"markupAmount": 123,
"markupRatio": 123
}
'import requests
url = "https://www.ruddr.io/api/workspace/project-expenses"
payload = {
"date": "2023-12-25",
"amount": 123,
"projectId": "<string>",
"expenseCategoryId": "<string>",
"isBillable": True,
"vendor": "<string>",
"notes": "<string>",
"markupAmount": 123,
"markupRatio": 123
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
date: '2023-12-25',
amount: 123,
projectId: '<string>',
expenseCategoryId: '<string>',
isBillable: true,
vendor: '<string>',
notes: '<string>',
markupAmount: 123,
markupRatio: 123
})
};
fetch('https://www.ruddr.io/api/workspace/project-expenses', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.ruddr.io/api/workspace/project-expenses",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'date' => '2023-12-25',
'amount' => 123,
'projectId' => '<string>',
'expenseCategoryId' => '<string>',
'isBillable' => true,
'vendor' => '<string>',
'notes' => '<string>',
'markupAmount' => 123,
'markupRatio' => 123
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://www.ruddr.io/api/workspace/project-expenses"
payload := strings.NewReader("{\n \"date\": \"2023-12-25\",\n \"amount\": 123,\n \"projectId\": \"<string>\",\n \"expenseCategoryId\": \"<string>\",\n \"isBillable\": true,\n \"vendor\": \"<string>\",\n \"notes\": \"<string>\",\n \"markupAmount\": 123,\n \"markupRatio\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://www.ruddr.io/api/workspace/project-expenses")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"date\": \"2023-12-25\",\n \"amount\": 123,\n \"projectId\": \"<string>\",\n \"expenseCategoryId\": \"<string>\",\n \"isBillable\": true,\n \"vendor\": \"<string>\",\n \"notes\": \"<string>\",\n \"markupAmount\": 123,\n \"markupRatio\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.ruddr.io/api/workspace/project-expenses")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"date\": \"2023-12-25\",\n \"amount\": 123,\n \"projectId\": \"<string>\",\n \"expenseCategoryId\": \"<string>\",\n \"isBillable\": true,\n \"vendor\": \"<string>\",\n \"notes\": \"<string>\",\n \"markupAmount\": 123,\n \"markupRatio\": 123\n}"
response = http.request(request)
puts response.read_body{
"id": "7e3a1f82-b54d-4c89-a2f1-9d6e0c3b5a47",
"date": "2025-03-14",
"amount": 2450.75,
"total": 2940.9,
"isBillable": true,
"vendor": "Delta Airlines",
"notes": "Flight to client site for Q1 kickoff",
"createdAt": "2025-03-14T18:23:41.502Z",
"markupMethod": "percentage",
"markupAmount": null,
"markupRatio": 0.2,
"markup": 490.15,
"project": {
"id": "c50fafe3-4ec1-44f2-8a61-ddb3abcc55bb",
"name": "Website Redesign",
"client": {
"id": "aa39afdb-e168-4956-b061-41c7c62e8c2e",
"name": "Acme Corp"
}
},
"expenseCategory": {
"id": "175e0635-ac9e-4880-8492-07fa584f1b15",
"name": "Airfare"
},
"invoiced": false
}Create a project expense
curl --request POST \
--url https://www.ruddr.io/api/workspace/project-expenses \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"date": "2023-12-25",
"amount": 123,
"projectId": "<string>",
"expenseCategoryId": "<string>",
"isBillable": true,
"vendor": "<string>",
"notes": "<string>",
"markupAmount": 123,
"markupRatio": 123
}
'import requests
url = "https://www.ruddr.io/api/workspace/project-expenses"
payload = {
"date": "2023-12-25",
"amount": 123,
"projectId": "<string>",
"expenseCategoryId": "<string>",
"isBillable": True,
"vendor": "<string>",
"notes": "<string>",
"markupAmount": 123,
"markupRatio": 123
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
date: '2023-12-25',
amount: 123,
projectId: '<string>',
expenseCategoryId: '<string>',
isBillable: true,
vendor: '<string>',
notes: '<string>',
markupAmount: 123,
markupRatio: 123
})
};
fetch('https://www.ruddr.io/api/workspace/project-expenses', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.ruddr.io/api/workspace/project-expenses",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'date' => '2023-12-25',
'amount' => 123,
'projectId' => '<string>',
'expenseCategoryId' => '<string>',
'isBillable' => true,
'vendor' => '<string>',
'notes' => '<string>',
'markupAmount' => 123,
'markupRatio' => 123
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://www.ruddr.io/api/workspace/project-expenses"
payload := strings.NewReader("{\n \"date\": \"2023-12-25\",\n \"amount\": 123,\n \"projectId\": \"<string>\",\n \"expenseCategoryId\": \"<string>\",\n \"isBillable\": true,\n \"vendor\": \"<string>\",\n \"notes\": \"<string>\",\n \"markupAmount\": 123,\n \"markupRatio\": 123\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://www.ruddr.io/api/workspace/project-expenses")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"date\": \"2023-12-25\",\n \"amount\": 123,\n \"projectId\": \"<string>\",\n \"expenseCategoryId\": \"<string>\",\n \"isBillable\": true,\n \"vendor\": \"<string>\",\n \"notes\": \"<string>\",\n \"markupAmount\": 123,\n \"markupRatio\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.ruddr.io/api/workspace/project-expenses")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"date\": \"2023-12-25\",\n \"amount\": 123,\n \"projectId\": \"<string>\",\n \"expenseCategoryId\": \"<string>\",\n \"isBillable\": true,\n \"vendor\": \"<string>\",\n \"notes\": \"<string>\",\n \"markupAmount\": 123,\n \"markupRatio\": 123\n}"
response = http.request(request)
puts response.read_body{
"id": "7e3a1f82-b54d-4c89-a2f1-9d6e0c3b5a47",
"date": "2025-03-14",
"amount": 2450.75,
"total": 2940.9,
"isBillable": true,
"vendor": "Delta Airlines",
"notes": "Flight to client site for Q1 kickoff",
"createdAt": "2025-03-14T18:23:41.502Z",
"markupMethod": "percentage",
"markupAmount": null,
"markupRatio": 0.2,
"markup": 490.15,
"project": {
"id": "c50fafe3-4ec1-44f2-8a61-ddb3abcc55bb",
"name": "Website Redesign",
"client": {
"id": "aa39afdb-e168-4956-b061-41c7c62e8c2e",
"name": "Acme Corp"
}
},
"expenseCategory": {
"id": "175e0635-ac9e-4880-8492-07fa584f1b15",
"name": "Airfare"
},
"invoiced": false
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
The date (YYYY-MM-DD) of the expense.
The total amount of the expense.
The project ID (uuid) for this expense.
The expense category ID (uuid) for this expense.
Whether the expense is billable to the client. Can only be true on billable projects.
The vendor for the expense (max 255 characters).
Any notes about the expense (max 1024 characters).
The method used to calculate markup. Either amount (fixed dollar amount) or percentage (ratio of the expense amount).
amount, percentage, null The fixed markup amount. Required when markupMethod is amount.
The markup ratio (0–1). Required when markupMethod is percentage.
Response
200
The unique identifier for the object.
The date of the expense. Will be in the form YYYY-MM-DD.
The total amount of the expense.
The total billed amount of the expense, including any markup.
Whether the expense is billable to the client. Can only be true on billable projects.
The vendor for the expense.
Any notes about the expense.
The timestamp when the object was created.
The method used to calculate markup. Either amount (fixed dollar amount) or percentage (ratio of the expense amount).
amount, percentage, null The fixed markup amount. Present when markupMethod is amount, otherwise null.
The markup ratio (0–1). Present when markupMethod is percentage, otherwise null.
The calculated markup value. null when no markup method is set.
The project this expense belongs to.
Show child attributes
Show child attributes
The expense category assigned to this expense.
Show child attributes
Show child attributes
Whether the expense has been invoiced.