How to create a simple API

This article demonstrates how to create a simple RESTful API that makes your data accessible to external applications and services or internal custom plugins.

:information_source: Note: The API in the model is only used to expose the API of the modeled application externally; work with any external APIs is modeled in the business logic section using sequential workflows.

[!success]- Prerequisites for proceeding

To follow along, you must meet the following prerequisites:

We will perform the following actions:

  1. Retrieve the entire list of items
  2. Retrieve the details of a specific item from the list
  3. Update an existing item
  4. Delete an item

As an example, we will use the simple task manager from the initial tutorial. We will list all tasks and then work with one of them.

:information_source: If you are new to application development or unfamiliar with APIs, you may find the following videos useful:

Introduction

An API is one of the five main ORIGAM modeling areas:

ORIGAM provides both REST and SOAP APIs and currently supports the following HTTP methods:

  • GET
  • PUT
  • DELETE

It supports both JSON and XML formats; in this example, we will use only JSON.

There are two API privacy options: private or public. In this tutorial, we will create a public API — accessible to anyone once published, but limited to localhost during development.

In all cases, we will create a new Data Page designed to expose application data:

You can learn more about other API Page types in the documentation.

Getting ready to create the API

Our API requires a Data Structure to operate. Before creating the API page, we’ll first create one. You can name it the same as the API:

When working with a specific record, we will also need a Filter Set with a Filter that retrieves data based on a provided Id:

Now we are ready to create an API that provides data based on that Data Structure and its Filter.

Get the entire list of items

To retrieve a list of all records from the desired entity — in this case, Tasks — we need to configure the following attributes in the API Data Page:

This Data Page is based on our Data Structure, uses JSON (MimeType), and is available to all roles. It will be accessible at the URL:
https://localhost/api/public/tasks

Since AllowDELETE and AllowPUT are set to False, this endpoint will only allow data retrieval.

For example, suppose the application contains these three tasks:

When we call the new API at https://localhost/api/public/tasks, we receive the following JSON data:

{
  "ROOT": {
    "Task": [
      {
        "Status_Id": "376ae614-1381-4ff5-b894-9c96c7978ead",
        "Name": "Create accounts",
        "AssignedTo_Id": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "DueDate": "2025-11-30T00:00:00+01:00",
        "Priority_Id": "bae03329-491c-4b09-8345-f8d26f027e9b",
        "NotificationSent": false,
        "Description": "Create user accounts for all new users who joined this month",
        "Selected": false,
        "RecordCreated": "2025-02-18T13:56:18.073+01:00",
        "RecordUpdatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "Id": "5784a17e-15fe-4f1e-b612-6a35055f4c0c",
        "RecordCreatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "RecordUpdated": "2025-11-06T10:10:30.447+01:00"
      },
      {
        "Status_Id": "376ae614-1381-4ff5-b894-9c96c7978ead",
        "Name": "Create new roles",
        "AssignedTo_Id": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "DueDate": "2025-11-25T00:00:00+01:00",
        "Priority_Id": "70a0e603-144e-4e90-b83b-4cd9b78e1469",
        "NotificationSent": false,
        "Description": "Create two new roles",
        "Selected": false,
        "RecordCreated": "2025-03-10T12:46:34.463+01:00",
        "RecordUpdatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "Id": "e5bdc0ae-15e9-44ed-8162-45239657d47c",
        "RecordCreatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "RecordUpdated": "2025-11-06T10:10:48.71+01:00"
      },
      {
        "Status_Id": "376ae614-1381-4ff5-b894-9c96c7978ead",
        "Name": "Deactivate accounts",
        "AssignedTo_Id": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "DueDate": "2025-12-31T00:00:00+01:00",
        "Priority_Id": "298928a8-cef3-4060-9fa0-f21b0509631c",
        "NotificationSent": false,
        "Description": "Deactivate all unused accounts",
        "Selected": false,
        "RecordCreated": "2025-07-28T10:29:06.64+02:00",
        "RecordUpdatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "Id": "50c49bfd-8e05-42b1-adb4-b7cc4ff9f9da",
        "RecordCreatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "RecordUpdated": "2025-11-06T10:10:58.197+01:00"
      }
    ]
  }
}

Get the details of a specific item from the list

To target a specific record, add its Id to the URL. Additionally, configure a Data Structure Method that retrieves the record’s data based on its Id. Your Data Page configuration may look like this:

The URL might look like this:

https://localhost/api/public/tasks/5784a17e-15fe-4f1e-b612-6a35055f4c0c

This request will return the details (based on your Data Structure) of that record:

{
  "ROOT": {
    "Task": [
      {
        "Status_Id": "376ae614-1381-4ff5-b894-9c96c7978ead",
        "Name": "Create accounts",
        "AssignedTo_Id": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "DueDate": "2025-11-30T00:00:00+01:00",
        "Priority_Id": "bae03329-491c-4b09-8345-f8d26f027e9b",
        "NotificationSent": false,
        "Description": "Create user accounts for all new users who joined this month",
        "Selected": false,
        "RecordCreated": "2025-02-18T13:56:18.073+01:00",
        "RecordUpdatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "Id": "5784a17e-15fe-4f1e-b612-6a35055f4c0c",
        "RecordCreatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "RecordUpdated": "2025-11-06T10:10:30.447+01:00"
      }
    ]
  }
}

Create or update an existing record

To allow record creation or updating through your API, enable this functionality in the Data Page settings by setting AllowPUT to True:

:information_source: In ORIGAM, the PUT command is used for both record creation and updating. Neither POST nor PATCH methods are currently used.

When a PUT request is sent, there are two possible scenarios:

  1. A record with the specified Id already exists — it will be updated.
  2. A record with the specified Id does not exist — it will be created.

In both cases, follow these steps:

  • Include the Id in the URL, e.g.:
    PUT https://localhost/api/public/tasks/5784a17e-15fe-4f1e-b612-6a35055f4c0c
  • Create a separate parameter for the request body in your model:
  • Include the complete record structure in the request body — exactly as returned by the GET command, including all brackets and "ROOT", for example:
{
  "ROOT": {
    "Task": [
      {
        "Status_Id": "376ae614-1381-4ff5-b894-9c96c7978ead",
        "Name": "Create accounts",
        "AssignedTo_Id": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "DueDate": "2025-11-30T00:00:00+01:00",
        "Priority_Id": "bae03329-491c-4b09-8345-f8d26f027e9b",
        "NotificationSent": false,
        "Description": "Create user accounts for all new users who joined this month",
        "Selected": false,
        "RecordCreated": "2025-02-18T13:56:18.073+01:00",
        "RecordUpdatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "Id": "5784a17e-15fe-4f1e-b612-6a35055f4c0c",
        "RecordCreatedBy": "21c7c5cd-b373-43a6-aa40-aed4533686c2",
        "RecordUpdated": "2025-11-06T10:10:30.447+01:00"
      }
    ]
  }
}

:information_source: If you include only some fields in the request body, the remaining fields will be set to null or lost. Therefore, if you intend to update only specific fields (similar to a PATCH request), you must still provide the full record data and modify only the fields you wish to change.

Delete a record

To enable record deletion via the API, set AllowDELETE to True in your API configuration.

When a DELETE request with a valid Id is sent, the corresponding record will be deleted.
For example, this request:
DELETE https://localhost/api/public/tasks/5784a17e-15fe-4f1e-b612-6a35055f4c0c
will delete the record with that Id, if it exists. No request body is required.