Skip to content

Proposal: Add externalLinks, like externalDocs but allow more than one - #5467

Open
lornajane wants to merge 3 commits into
OAI:mainfrom
lornajane:proposal/doclinks
Open

Proposal: Add externalLinks, like externalDocs but allow more than one#5467
lornajane wants to merge 3 commits into
OAI:mainfrom
lornajane:proposal/doclinks

Conversation

@lornajane

@lornajane lornajane commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

This proposal is a suggested approach for addressing this long-standing issue #1034 where quite a lot of people have asked for the ability to add more than one resource at a time.

AI disclosure: talked through with Claude and got the sillier ideas out of the way before proposing this approach, but the writing is my own.

  • no schema changes are needed for this pull request

@lornajane
lornajane requested review from a team as code owners August 6, 2026 16:10
@lornajane lornajane changed the title Proposal: Add docLinks, like externalDocs but allow more than one Proposal: Add externalLinks, like externalDocs but allow more than one Aug 6, 2026
@akrabat

akrabat commented Aug 8, 2026

Copy link
Copy Markdown

As the External Documentation object is being extended with summary here, is it worth adding tags too?

I can imagine having more than one type of link in the list and it may be handy to be able to classify or filter them based on tag.

@lornajane

Copy link
Copy Markdown
Contributor Author

From TDC meeting: agreed to update the draft to add a kind field to classify link types

@lornajane

Copy link
Copy Markdown
Contributor Author

Proposal amended to add a kind field to give support for describing what type of resource is linked. The kind naming is aligned with the same "grouping" type of pattern that was used in the tags from OpenAPI 3.2 onwards.

@miqui

miqui commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

@lornajane

My 2 cents:
Today's externalDocs gives you one URL with no signal about what kind of thing it points to. An agent has to fetch it, read it, and infer relevance — expensive and unreliable at scale.
externalLinks + the kind field (auth, api-docs, changelog, etc., pulled from a shared registry) turns that into a lookup table. An agent can ask "does this operation have a kind: auth link?" without fetching anything, and only pull the resource that's actually relevant to the current task.

Very important on being optimal fetching + inference

one caveat:

kind is a free string, not an enum. The registry gives you recommended values, but nothing stops an author from writing kind: docz or leaving it off entirely. An agent's filtering logic needs a fallback (read summary/description with light NLP) for non-standard or missing values.

@baywet

baywet commented Aug 27, 2026

Copy link
Copy Markdown
Member

could / should we have a default value for kind? and maybe a reserved "documentation" kind? To functionally map with externalDocs.

I'm especially thinking about people upgrading to 3.3, who already have an externalDocs, and would want to get out of using deprecated fields. Having a reserved key that maps functionally, and maybe a default could make that upgrade path more straight forward.

Note: I'm not suggesting we can only have both a default and a reserved key, but we should consider each or potentially both.

@lornajane

Copy link
Copy Markdown
Contributor Author

I am not in favour of a default because I think no-particular-kind links are entirely fine and might be the mainstream use case for most users. We aren't upgrading an existing field (as we were with tags, where until 3.2 they were assumed to be navigation) but I think a registry entry for "docs" and a recommendation to use that when migrating from an existing externalDocs entry is a good idea. That way we aren't making assumptions about new entries without kind, but are also giving a clear upgrade path.

@miqui

miqui commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

the proposal says "any string value can be used" with a registry of common values. I think open vocabularies are agent-hostile in a specific way (and by no means I am an NLP expert, just going by my observations) have to fuzzy-match "auth", "authentication", "authn", "oauth" as probably-the-same-thing. So, my position is that I strongly feel we need the spec to say what the absence means . There will be teams not using the recommended registry (which I think its a good idea anyway).

@miqui miqui left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this proposal is a good one. But have pending comments on the default topic.

@lornajane

Copy link
Copy Markdown
Contributor Author

I don't think we usually explain anything about an unused optional field so I'm a bit surprised by that suggestion. I'm proposing a list of links. There's some optional data that some use cases might find useful. If that seems harmful, let's leave the kind field out for now.

@miqui

miqui commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

@lornajane We should still use kind. I don't think its harmful.

Check this out from 3.2 regarding this attrib in the security scheme object

deprecated | boolean | Any | Declares this security scheme to be deprecated. Consumers SHOULD refrain from usage of the declared scheme. Default value is false.

So, if the deprecated is not explicitly added to the oad, then I assume that this implies "false" (its. default value). And this is what I am referring to earlier.

@handrews

Copy link
Copy Markdown
Member

@miqui deprecated having a default is a bit different: Something is either deprecated or it isn't, and the sensible default is that it isn't.

External link kinds will always be open-ended (even if we were to somehow restrict them to registered values, as more values can always be added), so unlike a boolean (only two possible values), there is no closed set and therefore no inherent need to have a default from that closed set.

Regarding fuzzy matching, etc.: We will have the registry. We can decline registry entries that are trivial spelling differences (e.g. if we have "authn" we can reject "authentication"). API designers who want their external links to be more reliably used by agents can use registered values. We do not need to worry about those who do not care to add this level of information.

It's not the OAS's role to enforce that API designers do everything possible to support AI agents. We ensure that the mechanisms are there (kind and registry) but do not enforce that they are used. Notably, we also do not enforce that tags or examples are used, and any OAD intended for AI agent consumption really ought to make heavy use of those features.

@miqui

miqui commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Good points @handrews

Perhaps the deprecated attribute is not such a good example. How about this one from the header object.

required boolean Determines whether this header is mandatory. The default value is false.

Is it wrong for me to assume required is false even though it does not appear in the OAD?

Quick experiment:
Sonnet 5 (high)

output:

if required is omitted on a Header Object, it defaults to false (optional).

The Header Object shares its fixed fields with the Parameter Object's "Common Fixed Fields" section (4.21.1.1 references back to 4.12.2.1). That section's required row reads: "In the following description, if a field is not explicitly REQUIRED or described with a MUST or SHALL, it can be considered OPTIONAL." — and specifically for required itself, the field is described as optional with a default of false, except for path parameters (which don't apply to headers at all, since headers have no in location).

One nuance worth flagging: this "default false" rule applies uniformly across Header Objects since headers have no in: "path" location — that's the one case in the sibling Parameter Object where required is forced to true regardless of presence. Headers don't have that carve-out, so omission always means optional there.

I like the language inferred here by the model. The spec provides enough context for the agent to "know" what to do next.

kind is optional, so the same behavior should be expected with a default for this?

However, I can't recall now, but we did get into a thread last year about some attribute and/or definition not being present in the OAD... I think we resolved this, but overall I don't want to impact this proposal. It is a good one.

@karenetheridge

Copy link
Copy Markdown
Member

How about this one from the header object. ... Is it wrong for me to assume required is false even though it does not appear in the OAD?

Of course not. Both the spec and the schema are consistent, just the same as with deprecated: required has a boolean value and its default value is false.

The Header Object shares its fixed fields with the Parameter Object's "Common Fixed Fields" section (4.21.1.1 references back to 4.12.2.1). That section's required row reads: "In the following description, if a field is not explicitly REQUIRED or described with a MUST or SHALL, it can be considered OPTIONAL."

That quote is from section 4 (https://spec.openapis.org/oas/latest#objects-and-fields), which is applicable to all definitions in the OAS.

Although the schema is not normative, this is also how JSON Schema works: a property is optional (may be omitted entirely) unless it is listed as required by the required keyword. (More exactly, a property name under the properties keyword is ignored if there is no corresponding property in the data instance being validated: it produces neither a valid nor invalid result.)

The only OAS keywords with a default are those where the value may only consist of a closed set: required and default everywhere, most of the parameter object's properties (in, style, explode etc), security scheme types etc.

As Lorna said, not everything may have a kind, so an explicit default is not appropriate.

@miqui

miqui commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

@karenetheridge

The only OAS keywords with a default are those where the value may only consist of a closed set: required and default everywhere, most of the parameter object's properties (in, style, explode etc), security scheme types etc.

ok

..... (More exactly, a property name under the properties keyword is ignored if there is no corresponding property in the data instance being validated: it produces neither a valid nor invalid result.)

So, then we'll treat kind the same way. Let's see. Thanks a lot for your feedback.

@mikekistler mikekistler left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! 👍

Do we anticipate creating a registry for the kind field of extermalLinks? I didn't see that mentioned here.

@miqui

miqui commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

@mikekistler

Do we anticipate creating a registry for the kind field of extermalLinks? I didn't see that mentioned here.

Good callout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants