New: CentriCall AI voice agents that answer, qualify, and book around the clock

Centricone Technologies API and developer documentation

Everything on this site is readable and callable by machine. Here is the whole surface, with the exact requests to make.

In short
  • A small REST API with no authentication: one endpoint that accepts a project brief, and read-only endpoints describing what this company does.
  • Every page also answers to an Accept: text/markdown request at its own URL, so an agent can read the site without parsing HTML.
  • The whole surface is described by an OpenAPI 3.1 document at /openapi.json, and published again as ready-made tool definitions at /tools.json.
  • There is an MCP server at /mcp, and a command-line tool that wraps the same endpoints.
  • Endpoints are versioned in the URL path, and anything deprecated carries Deprecation and Sunset headers for at least twelve months before it is removed.

What the Centricone Technologies API is

Centricone Technologies is a software development company, not a SaaS platform — so this is deliberately a small API rather than a large one. It exists so that an agent acting for a person can do two things without scraping: find out what we do, and send us a project brief. Everything below is live and unauthenticated.

Authentication

There is none, and that is deliberate rather than unfinished. No registration, no API key, no token, no OAuth — every endpoint on this page is public and anonymous. Send no Authorization header; one will be ignored.

Because there is no key, the quotas below are enforced per client address rather than per account. See Rate limits.

Base URL and versioning

The API is versioned in the URL path. The current version is v1, and a breaking change will ship as /api/v2/ rather than by altering v1 in place.

Base URL
https://www.centriconetechnologies.com/api/v1

Every response carries an X-API-Version header. Additive changes — a new field on a response, a new optional request field, a new endpoint — happen within a version and are not breaking. Removing a field, renaming one, or tightening validation is breaking, and gets a new version.

Quickstart

Three requests that between them exercise the whole API. No setup, no key.

Check the API is up
curl -s https://www.centriconetechnologies.com/api/v1/health
List what this company does
curl -s https://www.centriconetechnologies.com/api/v1/services
Send a project brief
curl -s -X POST https://www.centriconetechnologies.com/api/v1/contact \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Dana Whitfield",
    "email": "dana@example.com",
    "company": "Example Logistics",
    "topic": "MVP development",
    "message": "We need a driver app and a dispatch dashboard for about 400 drivers.",
    "consent": true
  }'

Endpoints

MethodPathWhat it returns
GET/api/v1The endpoint index: every operation, the quotas, and where the descriptions live.
GET/api/v1/healthLiveness, API version, server time.
GET/api/v1/servicesEvery capability, with both page URLs.
GET/api/v1/solutionsEvery packaged engagement.
GET/api/v1/industriesEvery sector served.
GET/api/v1/pagesEvery page on the site, as JSON.
POST/api/v1/contactSubmits a project brief.
The full request and response schema for each is in /openapi.json.

Listing endpoints

The four read endpoints all return the same envelope: a count and an items array. Every item carries both the human URL and the Markdown URL for the same content, so a follow-up fetch never needs a URL to be assembled by hand.

GET /api/v1/services — response (abridged)
{
  "count": 8,
  "items": [
    {
      "slug": "artificial-intelligence",
      "name": "Artificial Intelligence",
      "description": "AI development services — LLM and RAG applications…",
      "path": "/services/artificial-intelligence",
      "url": "https://www.centriconetechnologies.com/services/artificial-intelligence",
      "markdownUrl": "https://www.centriconetechnologies.com/services/artificial-intelligence.md"
    }
  ]
}

Filtering a list

Every listing endpoint takes the same filters. None of them is required — with no parameters you get the whole list, which is what these endpoints did before the filters existed.

ParameterEndpointsWhat it does
slugservices, solutions, industriesExact match, case-insensitive. An unknown slug is an empty collection, not a 404.
collectionpagesOne section of the site — services, insights, case-studies, home, and so on.
qall fourCase-insensitive substring. Matched against name and description on the catalogues, and against the path on pages.
limitall fourFirst N results after filtering. An integer from 1 to 100; anything else is a 422 rather than a silent clamp.
count always reports what came back, not what matched before the limit.
Two filters, one request
curl -s "https://www.centriconetechnologies.com/api/v1/services?q=cloud&limit=3"

curl -s "https://www.centriconetechnologies.com/api/v1/pages?collection=insights&limit=5"

Unknown parameters are ignored rather than rejected, so a cache-buster or a tracking parameter cannot break a call.

Submitting a project brief

POST /api/v1/contact is the only endpoint that writes anything. It is not idempotent — sending the same body twice delivers two enquiries to a human, so retry only on a 5xx or a 429.

FieldTypeRequiredRules
namestringyesAt least 2 characters.
emailstringyesA valid email address.
topicstringyesOne of 11 values — see the enum in /openapi.json.
messagestringyesAt least 20 characters, at most 5000.
consentbooleanyesMust be true.
companystringnoFree text.
phonestringnoFree text.

A success is 200 {"ok": true}. It means the brief reached at least one of our delivery targets, not that a person has read it yet — we reply within one business day.

Reading any page as Markdown

Every page on this site serves a Markdown representation at its own URL, following the acceptmarkdown.com content-negotiation convention. This is usually a better way to read the site than the JSON endpoints: it is the full page content, not a summary.

Two ways to get the same Markdown
curl -s -H "Accept: text/markdown" https://www.centriconetechnologies.com/services/artificial-intelligence

curl -s https://www.centriconetechnologies.com/services/artificial-intelligence.md

Markdown responses carry Vary: Accept. Quality values are honoured, so Accept: text/html;q=0.9, text/markdown returns Markdown. An Accept header that rules out both text/html and text/markdown gets a 406. The home page as Markdown is /index.md.

Rate limits

Reads are limited to 120 requests per 60 seconds, and writes to 5 per 60 seconds, per client address. Every API response — successful ones included — reports the current state, so there is no need to discover the limit by hitting it.

Rate-limit headers on every /api/ response
RateLimit-Policy: "read";q=120;w=60
RateLimit: "read";r=118;t=57
RateLimit-Limit: 120
RateLimit-Remaining: 118
RateLimit-Reset: 57

RateLimit-Policy and RateLimit are the structured fields from the IETF draft-ietf-httpapi-ratelimit-headers draft; the RateLimit-Limit / -Remaining / -Reset triple is the older and still more widely read spelling of the same numbers. Exceeding a limit returns 429 with a Retry-After in seconds, which takes precedence over anything in the RateLimit field.

Every response under /api/ carries them — a 200, a 404 on a path that does not exist, a 405 on the wrong verb, a 422 on a rejected parameter. That is deliberate: the answers a client gets while it is still working out the shape of the API are exactly the ones it needs pacing information from, and they used to be the ones that shipped without it.

Errors

Every failure under /api/ returns JSON with the same shape. Branch on code, show error to a person, and act on hint. Nothing under /api/ will ever hand you an HTML error page.

422 Unprocessable Content
{
  "error": "Some required details were missing or malformed.",
  "code": "validation_failed",
  "hint": "Correct the fields listed in `details` and resend.",
  "status": 422,
  "docs": "https://www.centriconetechnologies.com/openapi.json",
  "details": [
    { "field": "email", "issue": "Required. Must be a valid email address." }
  ]
}
codeStatusWhat to do
malformed_json400Fix the JSON body and the Content-Type.
validation_failed422Correct the fields named in details.
method_not_allowed405Use the verb named in the Allow header.
route_not_found404Check the path against /openapi.json.
rate_limited429Wait for Retry-After seconds, then retry.
delivery_failed502Retry once after a short delay.
delivery_unavailable503Do not retry — email info@centriconetechnologies.com.

Deprecation policy

An endpoint is never removed without warning. When one is deprecated it keeps working for at least twelve months, and every response from it carries three headers for that entire period:

  • Deprecation — an RFC 9745 date stamp saying when it became deprecated.
  • Sunset — an RFC 8594 date saying when it stops answering.
  • Link — pointing at this page (rel="deprecation") and at the replacement (rel="successor-version").

It is also marked deprecated: true in /openapi.json from the day it is announced, so a generated client sees it without reading this page.

One endpoint is currently deprecated: the unversioned POST /api/contact, superseded by POST /api/v1/contact. It behaves identically and will keep answering until 2027-08-31.

Headers on a deprecated endpoint
Deprecation: @1756080000
Sunset: Tue, 31 Aug 2027 23:59:59 GMT
Link: <https://www.centriconetechnologies.com/developers#deprecation-policy>; rel="deprecation"; type="text/html",
      <https://www.centriconetechnologies.com/api/v1/contact>; rel="successor-version"

Machine-readable files

Six files describe this site to a machine. All are public, all are generated from the same content and the same operation list the pages and endpoints are built from, and none can list something the others do not.

FileFormatWhat it is for
/openapi.jsonOpenAPI 3.1The full API contract, with a complete argument schema on every operation and no $ref to dereference.
/tools.jsonJSONThe same operations as function-calling tool definitions, ready to pass to a model.
/.well-known/api-catalogRFC 9727 linksetWhere every resource on this page lives, for a client that knows the domain and nothing else.
/llms.txtMarkdownEvery page with a one-line summary, per llmstxt.org.
/sitemap.xmlXMLEvery indexable URL.
/robots.txttextCrawl rules.

Using this API for function calling

/openapi.json is written to be loaded directly as a tool definition. Every operation has a unique operationId, a one-line summary, a description explaining when to call it, a complete schema for its arguments, and a typed response schema — what a function-calling runtime needs to decide what to invoke, build the call, and read the answer back.

No $ref appears anywhere in that document. Every schema is inlined where it is used, because a tool definition is one self-contained schema with no surrounding document to resolve a pointer against — and dereferencing is the step where converters quietly drop types. Each operation also carries its whole argument schema in one place, at x-input-schema.

If you would rather not convert anything, /tools.json is the same operations already published as tool definitions — 7 of them, each with a name, a description, and a JSON Schema under both input_schema (Anthropic) and parameters (OpenAI, Google), plus the HTTP call to make if you are not going through the MCP server.

Fetch the spec, or the tools
curl -s https://www.centriconetechnologies.com/openapi.json

curl -s https://www.centriconetechnologies.com/tools.json

MCP server

There is a Model Context Protocol server at https://www.centriconetechnologies.com/mcp, speaking the Streamable HTTP transport of specification revision 2025-06-18. Point an MCP client at that URL — no key, no session, nothing to install.

Any MCP client that takes a URL
{
  "mcpServers": {
    "centricone": {
      "type": "http",
      "url": "https://www.centriconetechnologies.com/mcp"
    }
  }
}

It exposes 7 tools: getHealth, listServices, listSolutions, listIndustries, listPages, getPage, submitContactEnquiry. They are the operations documented above, so anything the REST API can answer the MCP server can — including getPage, which returns the Markdown of any page on this site.

The same thing by hand
curl -s -X POST https://www.centriconetechnologies.com/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

One JSON-RPC 2.0 request per POST — initialize, ping, tools/list, tools/call. The server is stateless: it issues no session id, opens no SSE stream, and answers a GET with a 405 that says so. A tool that fails returns an ordinary result with isError: true rather than a protocol error, so a model can read what went wrong and correct itself.

Client libraries and CLI

centricone is a command-line wrapper around everything on this page: one ESM package, no dependencies, using Node's own fetch.

Read the catalogue, and any page, from a shell
npx centricone services --q cloud
npx centricone page services/artificial-intelligence
npx centricone endpoints
CommandWhat it does
centricone healthChecks the API is responding.
centricone services | solutions | industriesLists a catalogue. Takes --slug, --q, --limit.
centricone pagesLists every page. Takes --collection, --q, --limit.
centricone page <path>Prints a page as Markdown.
centricone endpointsLists every endpoint in the API.
centricone toolsPrints the function-calling tool manifest.
centricone contactSubmits a project brief. --dry-run prints the body instead of sending it.
--json prints the raw response, and --base-url points the tool at another origin.

There is no language SDK beyond that, and this page will say so rather than list something that does not exist. The API is small enough that curl and fetch are the whole integration, and /openapi.json will generate a typed client in most languages if you want one.

Questions, or something here that is wrong? Email info@centriconetechnologies.com.