Developer Guides

API documentation for our suite of content optimization tools designed for AI search. Convert your content into structured, machine-readable formats that improve SEO and AI retrieval citation rates.

Authentication API

This API allows users to register and authenticate using email and password. It supports signup into a new or existing organisation, and returns a JWT token upon login.

Signup

You can create a new user account using the /auth/signup endpoint. Depending on whether you're creating a new organisation or joining an existing one, provide either orgName or orgId.

Note: If you provide the orgName field, this will create a new organisation with that name. If you want to join an existing organisation, use orgId instead.

Endpoint

POST /auth/signup

Request Body

{
  "email": "user@example.com",
  "password": "secretPassword123",
  "orgName": "My New Org"
}

or if joining an existing organisation:

{
  "email": "user@example.com",
  "password": "secretPassword123",
  "orgId": "123e4567-e89b-12d3-a456-426614174000"
}

Example (cURL)

curl -X POST https://api.subjct.ai/auth/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "secretPassword123",
    "orgName": "My New Org"
}'

Responses

  • 200 OK – Signup successful. Response body: "success"
  • 400 Bad Request – Missing or invalid parameters

Login

Log in with your registered email and password to receive a bearer token (JWT) for authenticated requests.

Endpoint

POST /auth/login

Request Body

{
  "email": "user@example.com",
  "password": "examplePassword"
}

Example (cURL)

curl -X POST https://api.subjct.ai/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "examplePassword"
}'

Response

{
  "token": "your.jwt.token.here"
}

Use this token in the Authorization header to access secured endpoints:

Authorization: Bearer your.jwt.token.here
    

Authentication Notes

  • All secure endpoints require the Authorization header with a valid JWT.
  • The token should be treated like a password — keep it secure.
  • Organisations are isolated — a user belongs to one organisation at a time.

Organisation API

This API allows users to retrieve details about their organisation. It returns metadata such as the organisation name, ID, creation date, and a list of secret keys.

Get Organisation Details

Use the following endpoint to retrieve information about the currently authenticated user's organisation.

Endpoint

GET /org

Headers

Authorization: Bearer your.jwt.token.here
      

Example (cURL)

curl -X GET https://api.subjct.ai/org \
  -H "Authorization: Bearer your.jwt.token.here"

Response

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "Subjct",
  "secretKeys": [
    "sk__abc123def456",
    "sk__ghi789jkl012"
  ],
  "createdAt": "2025-07-01T08:30:00Z",
  "updatedAt": "2025-07-20T14:05:00Z"
}

Fields

  • id: Unique organisation UUID
  • name: The name of the organisation
  • secretKeys: A list of secret keys used for securing API access
  • createdAt: When the organisation was created
  • updatedAt: Last update timestamp

Responses

  • 200 OK – Organisation info retrieved successfully
  • 401 Unauthorized – Missing or invalid authentication token

List Organisation Users

Retrieve a list of all users associated with the authenticated organisation. This is useful for admins who want to manage their team or display the user directory in a dashboard.

Endpoint

GET /org/users

Headers

Authorization: Bearer your.jwt.token.here
      

Example (cURL)

curl -X GET https://api.subjct.ai/org/users \
  -H "Authorization: Bearer your.jwt.token.here"

Response

[
  {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "email": "user1@example.com",
    "org": "223e4567-e89b-12d3-a456-426614174000",
    "roles": ["User"],
    "createdAt": "2024-07-20T15:00:00Z",
    "updatedAt": "2024-07-21T10:32:45Z"
  },
  {
    "id": "789e4567-e89b-12d3-a456-426614174999",
    "email": "admin@example.com",
    "org": "223e4567-e89b-12d3-a456-426614174000",
    "roles": ["Admin"],
    "createdAt": "2024-07-15T12:00:00Z",
    "updatedAt": "2024-07-21T11:00:00Z"
  }
]

Fields

  • id: Unique user UUID
  • email: User’s email address
  • org: UUID of the organisation the user belongs to
  • roles: List of assigned roles (e.g. User, Admin)
  • createdAt: When the user was added to the org
  • updatedAt: Last modification timestamp

Responses

  • 200 OK – Users listed successfully
  • 401 Unauthorized – Invalid or missing token
Property API

Property API

The Property API allows you to manage web properties within an organisation. A "property" represents a content source, such as a website, and includes configuration for scraping and content processing.

Creating a Property

You can create a property in two ways:

1. Simplified Method

Create a property by providing just a URL. The system will generate a default configuration.

This method is easier and faster to set up, making it ideal for quick starts. However, it may result in less precise scraping of the data initially. The good news is that the property’s scraping configuration can always be refined and improved later by using the property update endpoint to tailor the settings for better accuracy.

Endpoint

POST /property/{organisationID}/from/url

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json

Request Body

{
  "url": "https://example.com"
}

Example (cURL)

curl -X POST https://api.subjct.ai/property/ORG_ID/from/url \
  -H "Authorization: Bearer your.jwt.token.here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'

Response

{
  "id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
  "organisationId": "fedcba09-8765-4321-0fed-cba987654321",
  "icons": [
    {
      "url": "https://random-site-example.com/assets/favicon.png?v=12345",
      "mimetype": "image/png",
      "extension": "png",
      "width": 0,
      "height": 0,
      "hash": "f0e1d2c3b4a5968778695a4b3c2d1e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d"
    }
  ],
  "target": {
    "version": "0.0.0",
    "name": "random-site-example.com",
    "url": "https://random-site-example.com",
    "autoDiscovery": true,
    "rate": {
      "mrps": 3
    },
    "source": {
      "include": null,
      "exclude": null,
      "categories": null,
      "sitemaps": null,
      "rss": null
    },
    "type": "http",
    "parser": {
      "article": {
        "url": "",
        "type": "readability",
        "requiresJs": false,
        "fields": null
      }
    },
    "sortingPriorities": [
      {
        "type": "boolean",
        "id": "evergreen",
        "label": "Evergreen Articles",
        "active": true
      },
      {
        "type": "boolean",
        "id": "hot",
        "label": "Hot Articles",
        "active": true
      },
      {
        "type": "boolean",
        "id": "rank",
        "label": "Page Rank",
        "active": true
      },
      {
        "type": "entity",
        "id": "entities",
        "label": "Topic Pages: Other",
        "active": true
      },
      {
        "type": "entity",
        "id": "people",
        "label": "Topic Pages: People",
        "active": true
      },
      {
        "type": "entity",
        "id": "events",
        "label": "Topic Pages: Events",
        "active": true
      },
      {
        "type": "entity",
        "id": "locations",
        "label": "Topic Pages: Locations",
        "active": true
      },
      {
        "type": "entity",
        "id": "organisations",
        "label": "Topic Pages: Organisations",
        "active": true
      },
      {
        "type": "entity",
        "id": "products",
        "label": "Topic Pages: Products",
        "active": true
      },
      {
        "type": "date",
        "id": "publishedDate",
        "label": "Published Date",
        "active": true
      }
    ]
  },
  "script": {
    "enabled": false,
    "metrics": {
      "track": null
    },
    "linking": {
      "articleSelector": ""
    }
  },
  "jsonLd": {
    "articleSchemaName": ""
  }
}

2. Advanced Method (Preferred)

Create a property with full configuration details.

This method offers more control and precision over how the property is scraped and processed, ensuring higher data quality from the start. We recommend this approach for production use. If you need assistance crafting an optimal property configuration, our support team is available to help you build and customize it according to your needs.

Endpoint

POST /property

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json

Request Body

{
  "target": {
    "version": "0.0.0",
    "name": "random-site-example.com",
    "url": "https://random-site-example.com",
    "rate": {
      "mrps": 2
    },
    "autoDiscovery": false,
    "source": {
      "sitemaps": [
        {
          "path": "/wp-sitemap-posts-post-1.xml"
        }
      ]
    },
    "parser": {
      "article": {
          "type": "custom",
          "fields": [
            {
              "key": "title",
              "selector": "h1 > strong",
              "pipeline": [
                {
                  "method": "trim"
                }
              ]
            },
            {
              "key": "content",
              "selector": "div.entry",
              "pipeline": [
                {
                  "method": "trim"
                }
              ]
            },
            {
              "key": "html",
              "selector": "div.entry",
              "raw": true
            }
          ]
      },
      "topic": {
        "type": "custom",
        "fields": [
          {
            "key": "text",
            "selector": "h1 > strong",
            "pipeline": [
              {
                "method": "trim"
              }
            ]
          }
        ]
      }
    }
  }
}

Example (cURL)

curl -X POST https://api.subjct.ai/property \
  -H "Authorization: Bearer your.jwt.token.here" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "version": "0.0.0",
    "name": "random-site-example.com",
    "url": "https://random-site-example.com",
    "rate": {
      "mrps": 2
    },
    "autoDiscovery": false,
    "source": {
      "sitemaps": [
        {
          "path": "/wp-sitemap-posts-post-1.xml"
        }
      ]
    },
    "parser": {
      "article": {
          "type": "custom",
          "fields": [
            {
              "key": "title",
              "selector": "h1 > strong",
              "pipeline": [
                {
                  "method": "trim"
                }
              ]
            },
            {
              "key": "content",
              "selector": "div.entry",
              "pipeline": [
                {
                  "method": "trim"
                }
              ]
            },
            {
              "key": "html",
              "selector": "div.entry",
              "raw": true
            }
          ]
      },
      "topic": {
        "type": "custom",
        "fields": [
          {
            "key": "text",
            "selector": "h1 > strong",
            "pipeline": [
              {
                "method": "trim"
              }
            ]
          }
        ]
      }
    }
  }
}'

Response

{
  "id": "78a34370-7e0a-488b-b86d-68e486789668",
  "organisationId": "1bbb63dc-dc65-42a2-9708-8c417fb3df91",
  "icons": [
    {
      "url": "https://mnmlist.com/favicon.ico",
      "mimetype": "image/x-icon",
      "extension": "ico",
      "width": 0,
      "height": 0,
      "hash": "34285853c6c50ecf9f891f2c3ef8ed65a3f3996bb4427e47be8441d0b613ebd0"
    }
  ],
  "target": {
    "version": "0.0.0",
    "name": "mnmlist",
    "url": "https://mnmlist.com",
    "autoDiscovery": false,
    "rate": {
      "mrps": 2
    },
    "source": {
      "include": null,
      "exclude": null,
      "categories": null,
      "sitemaps": [
        {
          "type": "",
          "path": "/wp-sitemap-posts-post-1.xml",
          "regex": ""
        }
      ],
      "rss": null
    },
    "type": "",
    "parser": {
      "article": {
        "url": "",
        "type": "custom",
        "requiresJs": false,
        "fields": [
          {
            "key": "title",
            "selector": "h1 > strong",
            "attribute": "",
            "raw": false,
            "specialText": false,
            "matcher": "",
            "json": false,
            "path": "",
            "fields": null,
            "pipeline": [
              {
                "Method": "trim",
                "Args": null
              }
            ]
          },
          {
            "key": "content",
            "selector": "div.entry",
            "attribute": "",
            "raw": false,
            "specialText": false,
            "matcher": "",
            "json": false,
            "path": "",
            "fields": null,
            "pipeline": [
              {
                "Method": "trim",
                "Args": null
              }
            ]
          },
          {
            "key": "html",
            "selector": "div.entry",
            "attribute": "",
            "raw": true,
            "specialText": false,
            "matcher": "",
            "json": false,
            "path": "",
            "fields": null,
            "pipeline": null
          }
        ]
      },
      "topic": {
        "url": "",
        "type": "custom",
        "requiresJs": false,
        "fields": [
          {
            "key": "text",
            "selector": "h1 > strong",
            "attribute": "",
            "raw": false,
            "specialText": false,
            "matcher": "",
            "json": false,
            "path": "",
            "fields": null,
            "pipeline": [
              {
                "Method": "trim",
                "Args": null
              }
            ]
          }
        ]
      }
    },
    "sortingPriorities": null
  },
  "script": {
    "enabled": false,
    "metrics": {
      "track": null
    },
    "linking": {
      "articleSelector": ""
    }
  },
  "jsonLd": {
    "articleSchemaName": ""
  }
}

Update Property

Use this endpoint to update an existing property's details by its unique ID. Important: This is a PUT request, meaning it will replace the entire property object. You must send the full updated property data — not just the fields you want to change.

Endpoint

PUT /property/{id}

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json
    

Path Parameters

  • id: Unique ID of the property to update

Request Body

Provide the complete property configuration, including all required and optional fields. Omitting fields may result in data being lost.

Example (cURL)

curl -X PUT https://api.subjct.ai/property/PROPERTY_ID \
  -H "Authorization: Bearer your.jwt.token.here" \
  -H "Content-Type: application/json" \
  -d '{ ... (Full and updated property configuration) ...
}'

Response

{
  "id": "78a34370-7e0a-488b-b86d-68e486789668",
  "organisationId": "1bbb63dc-dc65-42a2-9708-8c417fb3df91",
  "icons": [
    {
      "url": "https://mnmlist.com/favicon.ico",
      "mimetype": "image/x-icon",
      "extension": "ico",
      "width": 0,
      "height": 0,
      "hash": "34285853c6c50ecf9f891f2c3ef8ed65a3f3996bb4427e47be8441d0b613ebd0"
    }
  ],
  "target": {
    "version": "0.0.0",
    "name": "mnmlist",
    "url": "https://mnmlist.com",
    "autoDiscovery": false,
    "rate": {
      "mrps": 2
    },
    "source": {
      "include": null,
      "exclude": null,
      "categories": null,
      "sitemaps": [
        {
          "type": "",
          "path": "/wp-sitemap-posts-post-1.xml",
          "regex": ""
        }
      ],
      "rss": null
    },
    "type": "",
    "parser": {
      "article": {
        "url": "",
        "type": "custom",
        "requiresJs": false,
        "fields": [
          {
            "key": "title",
            "selector": "h1 > strong",
            "attribute": "",
            "raw": false,
            "specialText": false,
            "matcher": "",
            "json": false,
            "path": "",
            "fields": null,
            "pipeline": [
              {
                "Method": "trim",
                "Args": null
              }
            ]
          },
          {
            "key": "content",
            "selector": "div.entry",
            "attribute": "",
            "raw": false,
            "specialText": false,
            "matcher": "",
            "json": false,
            "path": "",
            "fields": null,
            "pipeline": [
              {
                "Method": "trim",
                "Args": null
              }
            ]
          },
          {
            "key": "html",
            "selector": "div.entry",
            "attribute": "",
            "raw": true,
            "specialText": false,
            "matcher": "",
            "json": false,
            "path": "",
            "fields": null,
            "pipeline": null
          }
        ]
      },
      "topic": {
        "url": "",
        "type": "custom",
        "requiresJs": false,
        "fields": [
          {
            "key": "text",
            "selector": "h1 > strong",
            "attribute": "",
            "raw": false,
            "specialText": false,
            "matcher": "",
            "json": false,
            "path": "",
            "fields": null,
            "pipeline": [
              {
                "Method": "trim",
                "Args": null
              }
            ]
          }
        ]
      }
    },
    "sortingPriorities": null
  },
  "script": {
    "enabled": false,
    "metrics": {
      "track": null
    },
    "linking": {
      "articleSelector": ""
    }
  },
  "jsonLd": {
    "articleSchemaName": ""
  }
}

Responses

  • 200 OK – Property updated successfully
  • 400 Bad Request – Invalid input data
  • 401 Unauthorized – Invalid or missing authentication token
  • 403 Forbidden – Not authorized to update this property
  • 404 Not Found – Property not found
  • 500 Internal Server Error – Server error occurred

Get All Properties

Retrieve all properties for the authenticated organisation.

Endpoint

GET /property

Headers

Authorization: Bearer your.jwt.token.here
    

Example (cURL)

curl -X GET https://api.subjct.ai/property \
  -H "Authorization: Bearer your.jwt.token.here"

Response Headers

  • X-Total-Count: Total number of properties

Response Body

[
  {
    "id": "property-uuid",
    "organisationId": "org-uuid",
    (...),
  }
]

Responses

  • 200 OK – A list of properties retrieved successfully
  • 404 Not Found – Properties not found for the organisation
  • 401 Unauthorized – Missing or invalid authentication token

Get Property by ID

Retrieve detailed information about a property by its unique ID.

Endpoint

GET /property/{id}

Path Parameters

  • id (string): Unique ID of the property to retrieve

Headers

Authorization: Bearer your.jwt.token.here
    

Example (cURL)

curl -X GET https://api.subjct.ai/property/PROPERTY_ID \
  -H "Authorization: Bearer your.jwt.token.here"

Response Body

  {
    "id": "property-uuid",
    "organisationId": "org-uuid",
    (...),
  }

Responses

  • 200 OK – Property found and returned successfully
  • 404 Not Found – Property with specified ID does not exist
  • 401 Unauthorized – Missing or invalid authentication token

Suggest Scraping Configuration

Get a suggested scraping configuration for a given URL and category.

This helper endpoint returns a recommended parser configuration, which can be added to the parser field of the target section in a property — specifically under parser["{category}"], where {category} can be "article" or "topic".

Endpoint

POST /property/scraping/suggestion

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json
    

Request Body

{
  "url": "https://example.com/article/abc",
  "category": "article"  
}

Note: The category field must be either "article" or "topic".

Example (cURL)

curl -X POST https://api.subjct.ai/property/scraping/suggestion \
  -H "Authorization: Bearer your.jwt.token.here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/article/abc", "category": "article"}'

Responses

  • 200 OK – Suggested scraping configuration returned successfully
  • 400 Bad Request – Invalid category or request data
  • 500 Internal Server Error – Server error occurred
  • 401 Unauthorized – Missing or invalid authentication token

Test Scraping Configuration

Test scraping settings for a specific property using a URL and category.

Endpoint

POST /property/{id}/scraping/test

Path Parameters

  • id (string): Unique ID of the property to test scraping on

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json
    

Request Body

{
  "url": "https://example.com/article/123",
  "category": "article"  
}

Note: The category field must be either "article" or "topic".

Example (cURL)

curl -X POST https://api.subjct.ai/property/PROPERTY_ID/scraping/test \
  -H "Authorization: Bearer your.jwt.token.here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/article/123", "category": "article"}'

Responses

  • 200 OK – Scraping configuration and parsed content returned successfully
  • 400 Bad Request – Invalid request data
  • 403 Forbidden – Not authorized to test this property
  • 404 Not Found – Property not found
  • 500 Internal Server Error – Server error occurred
  • 401 Unauthorized – Missing or invalid authentication token

Ingestion API

The Ingestion API provides a set of endpoints for adding, scraping, and uploading content to your properties. It supports direct content submission (articles and topics), automated scraping, and bulk file uploads for various processing tasks.

Add a new Article

Directly submits a new article to a specific property within an organisation. This is useful for real-time content updates.

Endpoint

POST /ingest/{organisationID}/{propertyID}/article

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the target property.

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json
    

Request Body

{
  "externalId": "article-001",
  "url": "https://example.com/news/new-article-title",
  "title": "New Article Title",
  "content": "This is the full text content of the article...",
  "html": "<html> This is the full text content of the article... </html>"
}

Example (cURL)

curl -X POST https://api.subjct.ai/ingest/{organisationID}/{propertyID}/article \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your.jwt.token.here" \
  -d '{
    "externalId": "article-001",
    "url": "https://example.com/news/new-article-title",
    "title": "New Article Title",
    "content": "This is the full text content of the article...",
    "html": "<html>This is the full text content of the article...</html>"
  }'

Response

{
  "id": "d8f8b8c0-8c8e-4b4c-8c8e-8d8e8d8e8d8e",
  "externalId": "article-001",
  "organisationId": "123e4567-e89b-12d3-a456-426614174000",
  "propertyId": "223e4567-e89b-12d3-a456-426614174001",
  "contentHash": "a1b2c3d4e5f6...",
  "htmlHash": "f6e5d4c3b2a1..."
}

Responses

  • 200 OK – Article ingested successfully.
  • 400 Bad Request – Invalid input in the request body.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 404 Not Found – The specified organisation or property does not exist.
  • 409 Conflict – An article with the same URL but a different ID already exists.
  • 422 Unprocessable Entity – Validation exception (e.g., malformed fields).
  • 500 Internal Server Error – An unexpected error occurred during ingestion.

Add a new Topic

Directly submits a new topic page to a property.

Endpoint

POST /ingest/{organisationID}/{propertyID}/topic

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the target property.

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json
    

Request Body

{
  "externalId": "topic-xyz-789",
  "url": "https://example.com/topics/new-topic-title",
  "text":  "AI in Healthcare"
}

Example (cURL)

curl -X POST https://api.subjct.ai/ingest/{organisationID}/{propertyID}/topic \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your.jwt.token.here" \
  -d '{
      "externalId": "topic-xyz-789",
      "url": "https://example.com/topics/new-topic-title",
      "text":  "AI in Healthcare"
  }'

Response

{
  "id": "f4a4b4c0-4c4c-4b4c-8c8e-1a2b3c4d5e6f",
  "externalId": "topic-xyz-789",
  "organisationId": "123e4567-e89b-12d3-a456-426614174000",
  "propertyId": "223e4567-e89b-12d3-a456-426614174001"
}

Responses

  • 200 OK – Topic ingested successfully.
  • 400 Bad Request – Invalid input in the request body.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 404 Not Found – The specified organisation or property does not exist.
  • 422 Unprocessable Entity – Validation exception.
  • 500 Internal Server Error – An unexpected error occurred during ingestion.

Start a Scrape Job

Triggers a new scraping job for a given property based on its existing configuration. This initiates a background task to find and process content from the web.

Endpoint

POST /ingest/{organisationID}/{propertyID}/scrape

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the property to be scraped.

Headers

Authorization: Bearer your.jwt.token.here
    

Example (cURL)

curl -X POST https://api.subjct.ai/ingest/{organisationID}/{propertyID}/scrape \
  -H "Authorization: Bearer your.jwt.token.here"

Responses

  • 200 OK – Scraping job initiated successfully. The response body will contain a confirmation message.
  • 400 Bad Request – The property is not configured for scraping (e.g., no parser is set up, or auto-discovery is off and no sitemaps are provided).
  • 401 Unauthorized – Invalid or missing user credentials.
  • 404 Not Found – The specified organisation or property does not exist.
  • 500 Internal Server Error – Failed to publish the job creation message.

Upload a File for Ingestion

Uploads a file for bulk processing. The type of processing is determined by the ingestionType query parameter.

Endpoint

POST /ingest/{organisationID}/{propertyID}/upload

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the target property.
  • ingestionType (query, required): Defines the processing job. Can be one of: articles_parse, articles_ingest, topics_parse, topics_ingest.

Headers

Authorization: Bearer your.jwt.token.here
    

Request Body (multipart/form-data)

The request must contain a file. The required file type depends on the ingestionType:

  • For articles_parse or topics_parse, a .txt file containing one URL per line.
  • For articles_ingest or topics_ingest, a .csv or .jsonl file with structured data.

Example (cURL)

# Example for parsing a list of article URLs
curl -X POST "https://api.subjct.ai/ingest/{organisationID}/{propertyID}/upload?ingestionType=articles_parse" \
  -H "Authorization: Bearer your.jwt.token.here" \
  -F "file=@/path/to/your/urls.txt"

Responses

  • 200 OK – File upload successful and ingestion job started.
  • 400 Bad Request – Missing/invalid ingestionType, missing file, incorrect file extension, or invalid file headers.
  • 401 Unauthorized – Invalid or missing user credentials.
  • 404 Not Found – The specified organisation or property does not exist.
  • 500 Internal Server Error – The file upload failed or the job could not be published.

Article API

This API allows you to manage articles within a specific organisation and property. You can retrieve detailed information about an article, including its analysis and links, update its content, and find similar articles.

Get Article with Analysis and Links

Retrieves a single article by its ID, including the full results of any content analysis (like entities and summaries) and a list of detected internal and external links.

Endpoint

GET /article/{organisationID}/{propertyID}/{articleID}

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the target property.
  • articleID (path, required): The UUID of the article to retrieve.

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json
    

Example (cURL)

curl -X GET https://api.subjct.ai/article/org-uuid-123/prop-uuid-456/article-uuid-789 \
  -H "Authorization: Bearer your.jwt.token.here"

Response

{
  "analysis": {
    "category": "IAB19-9: General News",
    "createdAt": "2025-07-28T15:10:15.123456+01:00",
    "entities": [
      "Public Service Initiative"
    ],
    "events": [
      "Policy Changes Announced"
    ],
    "id": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
    "linkedEntities": [
      {
        "category": "entities",
        "kgId": "/g/12ab34cd56",
        "name": "Service Provider",
        "source": "enterprise_google_kg"
      }
    ],
    "locations": [
      "Capital City"
    ],
    "organisations": [
      "Government Department"
    ],
    "people": [
      "Jane Doe"
    ],
    "products": [],
    "sentiment": "-0.50",
    "summary": "This is a sample summary of the article, which discusses recent changes to a public program and its potential impact on citizens...",
    "updatedAt": "2025-07-28T15:12:34.567890+01:00"
  },
  "article": {
    "authors": [
      {
        "name": "John Smith",
        "url": "https://example-news.com/author/john-smith/"
      }
    ],
    "autoLinked": "",
    "breadcrumbs": [
      {
        "name": "Home",
        "position": 1,
        "url": "https://example-news.com/"
      }
    ],
    "categories": [
      "News"
    ],
    "content": "This is a sample of the article content. It describes a recent event and includes quotes from individuals involved...",
    "contentHash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "dateCreated": "2025-07-28T10:00:00Z",
    "datePublished": "2025-07-28T10:00:00Z",
    "dateUpdated": "2025-07-28T10:15:00Z",
    "evergreen": false,
    "externalId": "ext-article-9876",
    "hotPeriodEnd": null,
    "hotPeriodStart": null,
    "html": "<p>This is a sample of the article content. It describes a recent event...</p>",
    "htmlHash": "f1d2d2f924e986ac86fdf7b36c94bcdf32beec15c5a410fe9792b44821b5133b",
    "id": "article-uuid-789",
    "images": [
      {
        "alt": "A generic descriptive alt text for the image.",
        "title": "A sample image title describing the scene.",
        "url": "https://example-news.com/wp-content/uploads/2025/07/sample-image.jpg"
      }
    ],
    "jsonLd": "{\"@context\":\"https://schema.org\",\"@type\":\"NewsArticle\",\"headline\":\"Sample Article Title\"...}",
    "jsonLdGeneratedAt": "2025-07-28T15:12:34+01:00",
    "language": "en-US",
    "organisationId": "org-uuid-123",
    "propertyId": "prop-uuid-456",
    "title": "Sample Article About Recent Policy Changes",
    "url": "https://example-news.com/news/policy/sample-article-title/"
  },
  "entities": [
    {
      "title": "public service",
      "anchor": "Public Service",
      "category": "organisations",
      "occurs": 10
    }
  ],
  "links": [
    {
      "anchor": "related topic",
      "articleId": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
      "endCaret": 512,
      "id": "b2c3d4e5-f6a7-4b5c-8d9e-0f1a2b3c4d5e",
      "isCandidate": false,
      "isInternal": true,
      "isPhraseLink": false,
      "isPrior": true,
      "isTopic": false,
      "startCaret": 500,
      "url": "https://example-news.com/tag/related-topic/"
    }
  ]
}

Responses

  • 200 OK – Successful operation.
  • 400 Bad Request – Invalid input or malformed ID.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 425 Too Early – The article has been ingested but not yet processed. Try again later.

Update Article

Updates the content or metadata of an existing article using its ID. The request body should include only the fields you wish to update.

Endpoint

PUT /article/{organisationID}/{propertyID}/{articleID}

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the target property.
  • articleID (path, required): The UUID of the article to update.

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json

Request Body

Provide only the fields you want to change. For example, to update only the article's content:

{
  "content": "This is the new, updated content for the article."
}

Example (cURL)

curl -X PUT https://api.subjct.ai/article/org-uuid-123/prop-uuid-456/article-uuid-789 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your.jwt.token.here" \
  -d '{
    "content": "This is the new, updated content for the article."
  }'

Success Response (200 OK)

The response returns the IDs of the article and its parent resources, along with the fields that were successfully updated.

{
  "articleID": "ba628eb5-d041-5d3b-8ceb-9bee00d447ae",
  "organisationID": "1bbb63dc-dc65-42a2-9708-8c417fb3df91",
  "propertyID": "51015f08-54f2-4aff-84f8-7f5cf81b00c4",
  "content": "This is the new, updated content for the article."
}

Responses

  • 200 OK – Article updated successfully.
  • 400 Bad Request – Invalid request body.
  • 401 Unauthorized – Invalid or missing token.
  • 404 Not Found – The specified organisation, property, or article does not exist.
  • 500 Internal Server Error – An unexpected error occurred while updating.

Get Similar Articles

Retrieves a list of up to 10 articles that have summaries semantically similar to the specified article.

Endpoint

GET /article/{organisationID}/{propertyID}/{articleID}/similar_articles

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the target property.
  • articleID (path, required): The UUID of the source article for comparison.

Headers

Authorization: Bearer your.jwt.token.here
Content-Type: application/json
    

Example (cURL)

curl -X GET https://api.subjct.ai/article/org-uuid-123/prop-uuid-456/article-uuid-789/similar_articles \
  -H "Authorization: Bearer your.jwt.token.here"

Response

[
  {
    "id": "similar-article-uuid-001",
    "title": "A Very Similar Article",
    "href": "https://example.com/news/a-very-similar-article"
  },
  {
    "id": "similar-article-uuid-002",
    "title": "Another Related Topic",
    "href": "https://example.com/blog/another-related-topic"
  }
]

Responses

  • 200 OK – Successful operation.
  • 400 Bad Request – Invalid input or malformed ID.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 425 Too Early – The source article has not been processed yet. Try again later.

Analysis API

The Analysis API provides endpoints to retrieve detailed analysis results for articles, including entities, links, and to trigger JSON-LD generation.

Get Article Analysis Result

Retrieves the full analysis results for a specific article, including entities, categories, sentiment, and a summary.

Endpoint

GET /analysis/{organisationID}/{propertyID}/article/{articleID}

Parameters

  • organisationID (path, required): The UUID of the Organisation.
  • propertyID (path, required): The UUID of the Target Property.
  • articleID (path, required): The UUID of the Article.

Headers

Authorization: Bearer your.jwt.token.here

Example (cURL)

curl -X GET https://api.subjct.ai/analysis/org-uuid-123/prop-uuid-456/article/article-uuid-789 \
  -H "Authorization: Bearer your.jwt.token.here"

Success Response (200 OK)

{
  "category": "IAB3-4: Employment Advice",
  "createdAt": "2025-06-15T14:22:12.305123+01:00",
  "entities": [
    "Job Pathways",
    "employment seekers",
    "career mentor"
  ],
  "events": [
    "Job Pathways Expansion",
    "Ministry of Work consultation"
  ],
  "id": "e3f82b79-8a33-4d12-a6dc-4e2c5c9ab6d1",
  "linkedEntities": [
    {
      "category": "entities",
      "kgId": "/g/123xabc789",
      "name": "career mentor",
      "source": "enterprise_google_kg"
    },
    {
      "category": "organisations",
      "kgId": "/m/0d1w2x",
      "name": "Ministry of Work",
      "source": "enterprise_google_kg"
    }
  ],
  "locations": [
    "Manchester"
  ],
  "organisations": [
    "Job Pathways",
    "Ministry of Work"
  ],
  "people": [
    "Nina Patel",
    "Carlos Jennings"
  ],
  "products": [],
  "sentiment": "0.32",
  "summary": "This article discusses new developments in employment support through Job Pathways and associated programs...",
  "updatedAt": "2025-06-15T15:05:45.881912+01:00"
}

Responses

  • 200 OK – Successful operation.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 404 Not Found – The specified property or article does not exist.
  • 425 Too Early – The article has not been processed yet.

Get Article Links Result

Retrieves all the links (internal and external) found within a specific article.

Endpoint

GET /analysis/{organisationID}/{propertyID}/links/{articleID}

Parameters

  • organisationID (path, required): The UUID of the Organisation.
  • propertyID (path, required): The UUID of the Target Property.
  • articleID (path, required): The UUID of the Article.

Headers

Authorization: Bearer your.jwt.token.here

Example (cURL)

curl -X GET https://api.subjct.ai/analysis/org-uuid-123/prop-uuid-456/links/article-uuid-789 \
  -H "Authorization: Bearer your.jwt.token.here"

Success Response (200 OK)

[
  {
    "anchor": "jobseekers with special needs",
    "articleId": "e3f82b79-8a33-4d12-a6dc-4e2c5c9ab6d1",
    "endCaret": 512,
    "id": "a1f8e912-46a7-4cce-b6d9-91f947fe50cb",
    "isCandidate": false,
    "isInternal": true,
    "isPhraseLink": false,
    "isPrior": true,
    "isTopic": false,
    "startCaret": 492,
    "url": "https://www.example.org/tag/inclusive-employment/"
  },
  {
    "anchor": "Recent findings reveal mounting concerns",
    "articleId": "e3f82b79-8a33-4d12-a6dc-4e2c5c9ab6d1",
    "endCaret": 2140,
    "id": "0c23a965-e242-44c2-b3ee-31ad0d0f8de3",
    "isCandidate": false,
    "isInternal": false,
    "isPhraseLink": false,
    "isPrior": true,
    "isTopic": false,
    "startCaret": 2105,
    "url": "https://www.policywatch.org/employment-reform-under-scrutiny"
  }
]

Responses

  • 200 OK – Successful operation.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 404 Not Found – The specified property or article does not exist.
  • 425 Too Early – The article has not been processed yet.

Trigger JSON-LD Generation

Triggers an asynchronous process to generate JSON-LD structured data for the given article. To check the status, periodically poll the GET /article/{organisationID}/{propertyID}/{articleID} endpoint and check the article.jsonLdGeneratedAt timestamp.

Endpoint

POST /analysis/{organisationID}/{propertyID}/jsonLd/{articleID}

Parameters

  • organisationID (path, required): The UUID of the Organisation.
  • propertyID (path, required): The UUID of the Target Property.
  • articleID (path, required): The UUID of the Article.

Headers

Authorization: Bearer your.jwt.token.here

Example (cURL)

curl -X POST https://api.subjct.ai/analysis/org-uuid-123/prop-uuid-456/jsonLd/article-uuid-789 \
  -H "Authorization: Bearer your.jwt.token.here"

Success Response (200 OK)

A successful request returns an empty body, indicating the generation process has been triggered.

Responses

  • 200 OK – Trigger accepted successfully.
  • 400 Bad Request – JSON-LD already generated or invalid request.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 404 Not Found – The specified organisation, property, or article does not exist.
  • 500 Internal Server Error – An unexpected error occurred.

Metrics API

The Metrics API provides access to performance data for your organisations, properties, and individual articles.

Get Organisation-Wide Metrics

Returns overall metrics for the organisation, aggregated from its properties.

Endpoint

GET /metrics/{organisationID}

Parameters

  • organisationID (path, required): The UUID of the organisation.

Headers

Authorization: Bearer your.jwt.token.here

Example (cURL)

curl -X GET https://api.subjct.ai/metrics/org-uuid-123 \
  -H "Authorization: Bearer your.jwt.token.here"

Success Response (200 OK)

{
  "metrics": {
    "articles": 1578,
    "links": {
      "total": 18936,
      "internal": 12591,
      "external": 6345,
      "priorInternal": 11820
    },
    "words": {
      "total": 852150,
      "minimum": 52,
      "maximum": 3105,
      "average": 540
    },
    "labels": {
      "News": 1200,
      "Technology": 378
    },
    "categories": {
      "IAB19-11: Tech News": 950,
      "IAB1-1: Business": 628
    },
    "entities": {
      "entities > Artificial Intelligence": 1500,
      "people > John Doe": 250,
      "organisations > Example Corp": 400
    }
  }
}

Responses

  • 200 OK – Metrics successfully retrieved.
  • 400 Bad Request – Invalid input.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 425 Too Early – The data is still being processed.

Get Property-Level Metrics

Returns metrics for a specific property under a given organisation.

Endpoint

GET /metrics/{organisationID}/{propertyID}

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the property.

Headers

Authorization: Bearer your.jwt.token.here

Example (cURL)

curl -X GET https://api.subjct.ai/metrics/org-uuid-123/prop-uuid-456 \
  -H "Authorization: Bearer your.jwt.token.here"

Success Response (200 OK)

{
  "metrics": {
    "articles": 421,
    "links": {
      "total": 5052,
      "internal": 3357,
      "external": 1695,
      "priorInternal": 3152
    },
    "words": {
      "total": 227340,
      "minimum": 68,
      "maximum": 2890,
      "average": 540
    },
    "labels": {
      "Technology": 421
    },
    "categories": {
      "IAB19-11: Tech News": 421
    },
    "entities": {
      "entities > Artificial Intelligence": 400,
      "people > Jane Smith": 75,
      "organisations > Tech Inc": 120
    }
  }
}

Responses

  • 200 OK – Metrics successfully retrieved.
  • 400 Bad Request – Invalid input.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 425 Too Early – The data is still being processed.

Get Metrics for a Specific Article

Returns detailed metrics for a specific article under a property and organisation.

Endpoint

GET /metrics/{organisationID}/{propertyID}/article/{articleID}

Parameters

  • organisationID (path, required): The UUID of the organisation.
  • propertyID (path, required): The UUID of the property.
  • articleID (path, required): The UUID of the article.

Headers

Authorization: Bearer your.jwt.token.here

Example (cURL)

curl -X GET https://api.subjct.ai/metrics/org-uuid-123/prop-uuid-456/article/article-uuid-789 \
  -H "Authorization: Bearer your.jwt.token.here"

Success Response (200 OK)

{
  "metrics": {
    "articles": 1,
    "links": {
      "total": 15,
      "internal": 9,
      "external": 6,
      "priorInternal": 8
    },
    "words": {
      "total": 620,
      "minimum": 620,
      "maximum": 620,
      "average": 620
    },
    "labels": {
      "Technology": 1
    },
    "categories": {
      "IAB19-11: Tech News": 1
    },
    "entities": {
      "entities > Artificial Intelligence": 5,
      "entities > Machine Learning": 3,
      "people > Jane Smith": 1,
      "organisations > Tech Inc": 2
    }
  }
}

Responses

  • 200 OK – Metrics successfully retrieved.
  • 400 Bad Request – Invalid input.
  • 401 Unauthorized – Invalid or missing authentication token.
  • 425 Too Early – The article has not been processed yet.

Ready to Optimize Your Content?

Get in touch to find out more about our suite of content optimization tools built for AI search.

Join Beta