{"openapi":"3.1.0","info":{"title":"JUTEQ Public Information API","version":"1.0.0","description":"A read-only, unauthenticated API that helps AI agents and software clients understand JUTEQ, discover its enterprise cloud and AI services, and find authoritative contact links. It does not create engagements, collect leads, or expose customer data.","contact":{"name":"JUTEQ","url":"https://juteq.ca/contact","email":"info@juteq.ca"}},"jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","servers":[{"url":"https://juteq.ca","description":"JUTEQ public website"}],"tags":[{"name":"Company","description":"Authoritative public information about JUTEQ Inc."},{"name":"Services","description":"The consulting and engineering services published by JUTEQ."},{"name":"Insights","description":"Published JUTEQ articles and their HTML and Markdown representations."},{"name":"Agent discovery","description":"Natural-language discovery over JUTEQ public information."}],"paths":{"/api/v1/company":{"get":{"operationId":"getJuteqCompany","summary":"Get JUTEQ company information","description":"Returns JUTEQ identity, public contact details, office addresses, service area, and official profiles. Use this operation for entity resolution or contact questions.","tags":["Company"],"responses":{"200":{"description":"JUTEQ company information.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/json":{"schema":{"type":"object","required":["company"],"properties":{"company":{"$ref":"#/components/schemas/Company"}}}}}},"429":{"description":"The public API request limit was exceeded.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}},"Retry-After":{"description":"Seconds the client must wait before retrying after HTTP 429.","schema":{"type":"integer","minimum":1,"example":30}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/services":{"get":{"operationId":"listJuteqServices","summary":"List JUTEQ services","description":"Lists every published JUTEQ cloud, data, infrastructure, and AI service with its canonical page and core capabilities.","tags":["Services"],"responses":{"200":{"description":"The current published services.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/json":{"schema":{"type":"object","required":["services","total"],"properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/Service"}},"total":{"type":"integer","minimum":0}}}}}},"429":{"description":"The public API request limit was exceeded.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}},"Retry-After":{"description":"Seconds the client must wait before retrying after HTTP 429.","schema":{"type":"integer","minimum":1,"example":30}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/services/{slug}":{"get":{"operationId":"getJuteqServiceBySlug","summary":"Get one JUTEQ service","description":"Returns the published description, capabilities, and canonical page for one service. Retrieve the supported slugs from listJuteqServices.","tags":["Services"],"parameters":[{"name":"slug","in":"path","required":true,"description":"The stable URL slug of a published JUTEQ service.","schema":{"type":"string","enum":["agentic-ai","intelligent-infrastructure","cloud-transformation","genai","data-architecture","data-evaluation","knowledge-graphs"]}}],"responses":{"200":{"description":"The requested service.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/json":{"schema":{"type":"object","required":["service"],"properties":{"service":{"$ref":"#/components/schemas/Service"}}}}}},"404":{"description":"The requested service slug is not published.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"The public API request limit was exceeded.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}},"Retry-After":{"description":"Seconds the client must wait before retrying after HTTP 429.","schema":{"type":"integer","minimum":1,"example":30}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/blogs":{"get":{"operationId":"listJuteqPublishedBlogs","summary":"List published JUTEQ blogs","description":"Lists every currently published, non-deleted JUTEQ article with its canonical URL, publication metadata, and content-negotiated representations.","tags":["Insights"],"parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of published articles to return.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","required":false,"description":"Number of published articles to skip.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}],"responses":{"200":{"description":"The current published blog index.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/json":{"schema":{"type":"object","required":["blogs","total","limit","offset"],"properties":{"blogs":{"type":"array","items":{"$ref":"#/components/schemas/PublishedBlog"}},"total":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":1,"maximum":100},"offset":{"type":"integer","minimum":0,"maximum":10000}}}}}},"400":{"description":"The pagination parameters are invalid.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"The public API request limit was exceeded.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}},"Retry-After":{"description":"Seconds the client must wait before retrying after HTTP 429.","schema":{"type":"integer","minimum":1,"example":30}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"503":{"description":"The published blog index is temporarily unavailable.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/blogs/{slug}":{"get":{"operationId":"getJuteqPublishedBlogBySlug","summary":"Get one published JUTEQ blog","description":"Returns publication metadata and the negotiated HTML and Markdown URLs for one currently published JUTEQ article.","tags":["Insights"],"parameters":[{"name":"slug","in":"path","required":true,"description":"The stable URL slug of a published JUTEQ article.","schema":{"type":"string","minLength":1,"maxLength":200}}],"responses":{"200":{"description":"The requested published blog.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/json":{"schema":{"type":"object","required":["blog"],"properties":{"blog":{"$ref":"#/components/schemas/PublishedBlog"}}}}}},"404":{"description":"The requested blog slug is not currently published.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"The public API request limit was exceeded.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}},"Retry-After":{"description":"Seconds the client must wait before retrying after HTTP 429.","schema":{"type":"integer","minimum":1,"example":30}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"503":{"description":"The published blog index is temporarily unavailable.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/ask":{"get":{"operationId":"askJuteqPublicInformation","summary":"Search JUTEQ public information","description":"Accepts a natural-language query and returns ranked company or service records. This deterministic discovery endpoint does not generate advice or initiate a consulting engagement.","tags":["Agent discovery"],"parameters":[{"name":"query","in":"query","required":true,"description":"A natural-language question about JUTEQ or its services.","schema":{"type":"string","minLength":2,"maxLength":500},"example":"Who can help us build enterprise AI agents?"}],"responses":{"200":{"description":"Ranked public JUTEQ information.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskResponse"}}}},"400":{"description":"The natural-language query is missing or invalid.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"The public API request limit was exceeded.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}},"Retry-After":{"description":"Seconds the client must wait before retrying after HTTP 429.","schema":{"type":"integer","minimum":1,"example":30}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}},"post":{"operationId":"askJuteqPublicInformationWithJson","summary":"Search JUTEQ public information with JSON","description":"JSON request variant of the read-only natural-language discovery operation. It returns ranked public records and keeps no conversation state.","tags":["Agent discovery"],"requestBody":{"required":true,"description":"The query and optional NLWeb-compatible list mode.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskRequest"}}}},"responses":{"200":{"description":"Ranked public JUTEQ information.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskResponse"}}}},"400":{"description":"The JSON body or natural-language query is invalid.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"413":{"description":"The JSON request body is too large.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"415":{"description":"The request media type is not application/json.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"The public API request limit was exceeded.","headers":{"RateLimit-Policy":{"description":"The current application-instance load-shedding policy, expressed as an IETF structured field.","schema":{"type":"string","example":"\"public-api\";q=100;w=60"}},"RateLimit":{"description":"The units remaining on the serving application instance and seconds until its window resets.","schema":{"type":"string","example":"\"public-api\";r=99;t=60"}},"Retry-After":{"description":"Seconds the client must wait before retrying after HTTP 429.","schema":{"type":"integer","minimum":1,"example":30}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}}},"components":{"schemas":{"Address":{"type":"object","additionalProperties":false,"required":["country","streetAddress","addressLocality","addressRegion","postalCode","addressCountry"],"properties":{"country":{"type":"string"},"streetAddress":{"type":"string"},"addressLocality":{"type":"string"},"addressRegion":{"type":"string"},"postalCode":{"type":"string"},"addressCountry":{"type":"string","pattern":"^[A-Z]{2}$"}}},"Company":{"type":"object","additionalProperties":false,"required":["name","legalName","description","url","email","telephone","areaServed","languages","addresses","socialProfiles","contactUrl"],"properties":{"name":{"type":"string"},"legalName":{"type":"string"},"description":{"type":"string"},"url":{"type":"string","format":"uri"},"email":{"type":"string","format":"email"},"telephone":{"type":"string"},"areaServed":{"type":"string"},"languages":{"type":"array","items":{"type":"string"}},"addresses":{"type":"array","items":{"$ref":"#/components/schemas/Address"}},"socialProfiles":{"type":"array","items":{"type":"string","format":"uri"}},"contactUrl":{"type":"string","format":"uri"}}},"Service":{"type":"object","additionalProperties":false,"required":["slug","name","description","capabilities","url"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"capabilities":{"type":"array","minItems":1,"items":{"type":"string"}},"url":{"type":"string","format":"uri"}}},"ContentRepresentation":{"type":"object","additionalProperties":false,"required":["mediaType","url"],"properties":{"mediaType":{"type":"string","enum":["text/html","text/markdown"]},"url":{"type":"string","format":"uri"}}},"PublishedBlog":{"type":"object","additionalProperties":false,"required":["slug","title","description","url","publishedAt","updatedAt","author","categories","tags","readingTime","representations"],"properties":{"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"url":{"type":"string","format":"uri"},"publishedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"author":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"tags":{"type":"array","items":{"type":"string"}},"readingTime":{"type":["integer","null"],"minimum":1},"representations":{"type":"array","minItems":2,"items":{"$ref":"#/components/schemas/ContentRepresentation"}}}},"AskRequest":{"type":"object","additionalProperties":false,"required":["query"],"properties":{"query":{"type":"string","minLength":2,"maxLength":500},"mode":{"type":"string","enum":["list"],"default":"list"}}},"AskResult":{"type":"object","additionalProperties":false,"required":["url","name","site","score","description","schema_object"],"properties":{"url":{"type":"string","format":"uri"},"name":{"type":"string"},"site":{"type":"string","const":"juteq.ca"},"score":{"type":"number","minimum":0,"maximum":1},"description":{"type":"string"},"schema_object":{"type":"object"}}},"AskResponse":{"type":"object","additionalProperties":false,"required":["query_id","results","_meta"],"properties":{"query_id":{"type":"string","format":"uuid"},"results":{"type":"array","items":{"$ref":"#/components/schemas/AskResult"}},"_meta":{"type":"object","additionalProperties":false,"required":["response_type","version","no_match"],"properties":{"response_type":{"type":"string","const":"list"},"version":{"type":"string","const":"1.0"},"no_match":{"type":"boolean","description":"True when no published JUTEQ record shares a meaningful query token."}}}}},"ProblemDetails":{"type":"object","additionalProperties":false,"required":["type","title","status","code","message","resolution"],"properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer","minimum":400,"maximum":599},"code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]+$"},"message":{"type":"string"},"resolution":{"type":"string"},"instance":{"type":"string"}}}}}}