Email templates

Templates behind the emails NolaPro sends. action is the key that identifies which email a template is for; name is the human label. No lastchangedate, so no modifiedsince.

The object#

FieldTypeDescription
idread-onlyintegerNolaPro id.
actionstring(20)The code this resource is keyed by. Matching is case insensitive.
namestring(200)Human label for the template.
subjectstring(255)Subject line.
bodytextTemplate body.
cancelbooleanTrue once cancelled. Cancelled rows stay referenced by history.
externalidstring(100)Your own key for this email templates. Scoped to your company.

Endpoints#

POST/emailtemplates/batch 207

Create many.

Always answers 207, one result per item.

Requires scope setup:write.

Parameters
NameInTypeNotes
Idempotency-KeyheaderstringMakes the write safely retryable. Any unique string per logical operation; a UUID is fine. The failure this prevents is specific: the request succeeds, the response is lost to a timeout, you retry, and the customer is billed twice. With a key, the retry returns the original response - same status, same body, same id - and creates nothing. The body is part of the key's identity. Reusing a key with a different body is a bug on your side, not a retry, and answers 409 idempotency_replay rather than silently handing back the old response. Keys are remembered for 24 hours.
Body array
FieldTypeDescription
idread-onlyintegerNolaPro id.
actionstring(20)The code this resource is keyed by. Matching is case insensitive.
namestring(200)Human label for the template.
subjectstring(255)Subject line.
bodytextTemplate body.
cancelbooleanTrue once cancelled. Cancelled rows stay referenced by history.
externalidstring(100)Your own key for this email templates. Scoped to your company.
curl -X POST \
  'https://acme.nolapro.com/!/api/v2/emailtemplates/batch' \
  -H 'Authorization: Bearer $NP_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: your-unique-key' \
  -d '[
    {
        "id": 2,
        "action": "invoice",
        "name": "Invoice email",
        "subject": "",
        "body": "",
        "cancel": false
    }
]'
GET/emailtemplates 200403

List email templates.

Requires scope setup:read.

Parameters
NameInTypeNotes
namequerystringname. Partial match, case-insensitive.
actionquerystringPartial match, case insensitive.
cancelquerystringDefaults to false. Pass true for cancelled only, or any.
externalidquerystringExact match on your own key. Scoped to your company.
includequerystringComma-separated extras to embed. Only custom_fields is available: the extra fields this install has defined on the record. Off by default, and an unrecognised value is refused rather than ignored. See Conventions.
When it fails
StatusCodeMeaning
403insufficient_scopeToken lacks emailtemplates:read.
curl \
  'https://acme.nolapro.com/!/api/v2/emailtemplates' \
  -H 'Authorization: Bearer $NP_TOKEN'
POST/emailtemplates 201400409

Create.

Requires scope setup:write.

Parameters
NameInTypeNotes
Idempotency-KeyheaderstringMakes the write safely retryable. Any unique string per logical operation; a UUID is fine. The failure this prevents is specific: the request succeeds, the response is lost to a timeout, you retry, and the customer is billed twice. With a key, the retry returns the original response - same status, same body, same id - and creates nothing. The body is part of the key's identity. Reusing a key with a different body is a bug on your side, not a retry, and answers 409 idempotency_replay rather than silently handing back the old response. Keys are remembered for 24 hours.
Body
FieldTypeDescription
idread-onlyintegerNolaPro id.
actionstring(20)The code this resource is keyed by. Matching is case insensitive.
namestring(200)Human label for the template.
subjectstring(255)Subject line.
bodytextTemplate body.
cancelbooleanTrue once cancelled. Cancelled rows stay referenced by history.
externalidstring(100)Your own key for this email templates. Scoped to your company.
When it fails
StatusCodeMeaning
400invalid_requestA required field was missing or invalid.
409duplicateThat code is already in use.
curl -X POST \
  'https://acme.nolapro.com/!/api/v2/emailtemplates' \
  -H 'Authorization: Bearer $NP_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: your-unique-key' \
  -d '{
    "id": 2,
    "action": "invoice",
    "name": "Invoice email",
    "subject": "",
    "body": "",
    "cancel": false
}'
Response 201
{
    "id": 2,
    "action": "invoice",
    "name": "Invoice email",
    "subject": "",
    "body": "",
    "cancel": false
}
GET/emailtemplates/{id} 200404

Retrieve one record.

Requires scope setup:read.

Parameters
NameInTypeNotes
idrequiredpathintegerThe record id.
includequerystringComma-separated extras to embed. Only custom_fields is available: the extra fields this install has defined on the record. Off by default, and an unrecognised value is refused rather than ignored. See Conventions.
When it fails
StatusCodeMeaning
404not_foundNo record with that id.
curl \
  'https://acme.nolapro.com/!/api/v2/emailtemplates/104' \
  -H 'Authorization: Bearer $NP_TOKEN'
Response 200
{
    "id": 2,
    "action": "invoice",
    "name": "Invoice email",
    "subject": "",
    "body": "",
    "cancel": false
}
PATCH/emailtemplates/{id} 200404409

Update.

Requires scope setup:write.

Parameters
NameInTypeNotes
idrequiredpathintegerThe record id.
Idempotency-KeyheaderstringMakes the write safely retryable. Any unique string per logical operation; a UUID is fine. The failure this prevents is specific: the request succeeds, the response is lost to a timeout, you retry, and the customer is billed twice. With a key, the retry returns the original response - same status, same body, same id - and creates nothing. The body is part of the key's identity. Reusing a key with a different body is a bug on your side, not a retry, and answers 409 idempotency_replay rather than silently handing back the old response. Keys are remembered for 24 hours.
Body
FieldTypeDescription
idread-onlyintegerNolaPro id.
actionstring(20)The code this resource is keyed by. Matching is case insensitive.
namestring(200)Human label for the template.
subjectstring(255)Subject line.
bodytextTemplate body.
cancelbooleanTrue once cancelled. Cancelled rows stay referenced by history.
externalidstring(100)Your own key for this email templates. Scoped to your company.
When it fails
StatusCodeMeaning
404not_foundNo record with that id.
409stale_recordIf-Match did not match.
curl -X PATCH \
  'https://acme.nolapro.com/!/api/v2/emailtemplates/104' \
  -H 'Authorization: Bearer $NP_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: your-unique-key' \
  -d '{
    "id": 2,
    "action": "invoice",
    "name": "Invoice email",
    "subject": "",
    "body": "",
    "cancel": false
}'
Response 200
{
    "id": 2,
    "action": "invoice",
    "name": "Invoice email",
    "subject": "",
    "body": "",
    "cancel": false
}
DELETE/emailtemplates/{id} 200403404

Cancel.

Sets the cancel flag. Nothing is removed.

Requires scope setup:cancel.

Parameters
NameInTypeNotes
idrequiredpathintegerThe record id.
Idempotency-KeyheaderstringMakes the write safely retryable. Any unique string per logical operation; a UUID is fine. The failure this prevents is specific: the request succeeds, the response is lost to a timeout, you retry, and the customer is billed twice. With a key, the retry returns the original response - same status, same body, same id - and creates nothing. The body is part of the key's identity. Reusing a key with a different body is a bug on your side, not a retry, and answers 409 idempotency_replay rather than silently handing back the old response. Keys are remembered for 24 hours.
When it fails
StatusCodeMeaning
403insufficient_scopeNeeds emailtemplates:cancel.
404not_foundNo record with that id.
curl -X DELETE \
  'https://acme.nolapro.com/!/api/v2/emailtemplates/104' \
  -H 'Authorization: Bearer $NP_TOKEN'
Response 200
{
    "id": 2,
    "action": "invoice",
    "name": "Invoice email",
    "subject": "",
    "body": "",
    "cancel": false
}
GET/emailtemplates/{id}/attachments 200404

List files attached to an email template.

The attachments on this email template, newest first. Accepted filedefinitionid values: 46 (default 46). Metadata only - each file's bytes are at GET /attachments/{id}/content.

Requires scope setup:read.

Parameters
NameInTypeNotes
idrequiredpathintegerThe email template id.
filedefinitionidqueryintegerOnly files in this list. Accepted filedefinitionid values: 46 (default 46).
filecategoryidqueryintegerOnly files filed under this category.
filenamequerystringPartial match on the file name, case insensitive.
When it fails
StatusCodeMeaning
404not_foundNo email template with that id in this company.
curl \
  'https://acme.nolapro.com/!/api/v2/emailtemplates/104/attachments' \
  -H 'Authorization: Bearer $NP_TOKEN'
POST/emailtemplates/{id}/attachments 201400404409413415422

Attach a file to an email template.

multipart/form-data with one file part; see the AttachmentUpload schema for the other parts. Accepted filedefinitionid values: 46 (default 46). Answers 201 with the attachment's metadata and Location: /attachments/{id}. Check _meta.warnings for datatype_truncated and stored_under_parent_company.

Requires scope setup:write.

Parameters
NameInTypeNotes
idrequiredpathintegerThe email template id.
Idempotency-KeyheaderstringMakes the write safely retryable. Any unique string per logical operation; a UUID is fine. The failure this prevents is specific: the request succeeds, the response is lost to a timeout, you retry, and the customer is billed twice. With a key, the retry returns the original response - same status, same body, same id - and creates nothing. The body is part of the key's identity. Reusing a key with a different body is a bug on your side, not a retry, and answers 409 idempotency_replay rather than silently handing back the old response. Keys are remembered for 24 hours.
Body multipart/form-data
FieldTypeDescription
filerequiredstringThe file. Exactly one part named file; a second one, or file[], is 400 invalid_request so an idempotent retry can never half-succeed. Empty is refused. Over the cap (the smaller of APIV2_MAX_UPLOAD_BYTES, 64 MB by default, and PHP's upload_max_filesize / post_max_size) is 413 payload_too_large naming the limit that applied.
filenamestring(255)Overrides the part's file name.
notestextFree text shown beside the file.
filedefinitionidintegerOnly when the parent accepts more than one list. Anything the parent does not accept is 422 unknown_value naming the accepted ids.
filecategoryidintegerCategory by id.
filecategorystring(255)Category by name. Sent with filecategoryid and disagreeing is 422 conflicting_reference.
When it fails
StatusCodeMeaning
400unknown_parameterA form field that is not on the AttachmentUpload schema.
400invalid_typefiledefinitionid or filecategoryid that is not an integer.
404not_foundNo email template with that id in this company.
409upload_limit_reachedThis file list allows a fixed number of files on an email template and it is full. Remove one first.
413payload_too_largeThe file is over the cap. The body names the limit that applied.
415multipart_requiredThe body was not multipart/form-data.
422unknown_valuefiledefinitionid is not one this email template accepts, or the category does not exist in this company.
curl -X POST \
  'https://acme.nolapro.com/!/api/v2/emailtemplates/104/attachments' \
  -H 'Authorization: Bearer $NP_TOKEN' \
  -H 'Idempotency-Key: your-unique-key' \
  -F 'file=@grant-letter-signed.pdf' \
  -F 'filename=grant-letter-signed.pdf' \
  -F 'notes=Signed copy received 21 Sep' \
  -F 'filedefinitionid=8' \
  -F 'filecategory=Receipts'