diff --git a/versions/3.0.md b/versions/3.0.md
index 2bfca451ce..96c7814515 100644
--- a/versions/3.0.md
+++ b/versions/3.0.md
@@ -938,7 +938,7 @@ default:
```
#### Response Object
-Describes a single response from an API Operation.
+Describes a single response from an API Operation, including design-time, static `links` to operations based on the response.
##### Fixed Fields
Field Name | Type | Description
@@ -947,6 +947,8 @@ Field Name | Type | Description
schema | [Schema Object](#schemaObject) | A definition of the response structure. It can be a primitive, an array or an object. If this field does not exist, it means no content is returned as part of the response. As an extension to the [Schema Object](#schemaObject), its root `type` value may also be `"file"`. This SHOULD be accompanied by a relevant `produces` media type.
headers | [Headers Object](#headersObject) | A list of headers that are sent with the response.
examples | [Example Object](#exampleObject) | An example of the response message.
+links | [Links Object](#linksObject) | An object representing operations related to the response payload.
+
##### Patterned Objects
@@ -1123,6 +1125,397 @@ application/json:
breed: Mixed
```
+#### Links Object
+The links object represents a set of possible design-time links for a response. The presence of a link does not guarantee the caller's ability to successfully call invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.
+
+As opposed to _dynamic_ links--that is, links provided **in** the response payload, the OAS linking mechanism does not require that link information be provided in a specific response format at runtime.
+
+For computing links, and providing instructions to execute them, a mechanism is defined for accessing values in a response and using them as variables while invoking the linked operation.
+
+Field Name | Type | Description
+---|:---:|---
+$ref | `string` | If present, a reference to another Links Object. Note, the presence of `$ref` in the Links Object will cause all _Patterned Objects_ to be ignored.
+
+Field Pattern | Type | Description
+---|:---:|---
+link name | [Link Object](#linkObject) | A short name for the link, following the naming constraints of the definitions name. The link shall reference a single Link Object, or a JSON Reference to a single link object
+
+
+### Link Object
+The `Link Object` is responsible for defining a possible operation based on a single response.
+
+Field Name | Type | Description
+---|:---:|---
+href | url | a relative or absolute URL to a linked resource. This field is mutually exclusive with the `operationId` field.
+operationId | string | the name of an _existing_, resolvable OAS operation, as defined with a unique `operationId`. This field is mutually exclusive with the `href` field. Relative `href` values _may_ be used to locate an existing Operation Object in the OAS.
+parameters | Link Parameters Object | an Object representing parameters to pass to an operation as specified with `operationId` or identified via `href`.
+headers | Link Headers Object | an Object representing headers to pass to the linked resource.
+description | string | a description of the link, supports GFM.
+^x- | Any | Allows extensions to the OpenAPI Schema. The field name MUST begin with `x-`, for example, `x-internal-id`. The value can be `null`, a primitive, an array or an object. See [Specification Extensions](#specificationExtensions) for further details.
+
+Locating a linked resource may be performed by either a `href` or `operationId`. In the case of an `operationId`, it must be unique and resolved in the scope of the OAS document. Because of the potential for name clashes, consider the `href` syntax as the preferred method for specifications with external references.
+
+#### Response Payload Values
+
+Payload values are only available in parseable response payloads which match the advertised media-type. In all cases, if a value does _not_ exist, the parameter will be considered a `null` value (as opposed to an empty value) and _not_ passed as a parameter to the linked resource. In cases where a value is required, and a parameter is not supplied, the client _may_ choose to not follow the link definition.
+
+### Example
+
+Response payload:
+```json
+{
+ "id": "df71a505-07bc-458a-a5c0-73c0340d1ec7",
+ "firstname": "Ash",
+ "lastname": "Williams"
+}
+```
+
+Payload Variables:
+```yaml
+id: df71a505-07bc-458a-a5c0-73c0340d1ec7
+firstname: Ash
+lastname: Williams
+missingValue: null
+```
+
+In situations where variables appear in an array, an array of variables will be extracted. For example:
+
+```json
+[
+ { "color": "red" },
+ { "color": "green" },
+ { "color": "blue" }
+]
+```
+
+will be extracted as such:
+
+```json
+color: ["red", "green", "blue"]
+```
+
+The variables generated can be used in locations prescribed by the definition.
+
+
+### Variable substitution
+In all cases, _variables_ from request and responses may be substituted for link generation. The table below designates the source of the substitution value and the syntax for accessing it:
+
+Source Location | reference identifier | example value | example reference | notes
+---|:---|:---|:---
+HTTP Method | `$method` | `/users/{$method}` | The allowable values for the `$method` will be those for the HTTP operation
+Requested content type | `$accepts` | `/users/3?format={$accepts}` |
+Request parameter | `$request` | `/users/{$request.id}` | Request parameters must be declared in the `parameters` section for the operation or they cannot be used in substitution. This includes request headers
+Request body | `$requestBody` | `/users/{$requestBody.user.uuid}` | For operations which accept payloads, references may be made to portions of the `requestBody` or the entire body itself
+Request URL | `$url` | `/track?url={$url}` |
+Response value | `$response` | `{$response.uuid}` | Only the payload in the response can be accessed with the `$response` syntax
+Response header | `$responseHeader` | `{$responseHeader.Server}` | Single header values only are available.
+
+From the request, the `parameter`s used in calling the operation are made available through the `$request` syntax. For responses, the response payload may be used with the `$response` syntax. For both requests and responses, values will be substituted in the link in sections designated with the `$request` or `$response` keyword, surrounded by curly brackets `{}`.
+
+### Request parameter example
+Computing a link from a request operation like such:
+
+```yaml
+paths:
+ /users/{id}:
+ parameters:
+ - name: id
+ in: path
+ required: true
+ description: the user identifier, as userId or username
+ schema:
+ type: string
+ responses:
+ 200:
+ description: the user being returned
+ schema:
+ type: object
+ properties:
+ uuid: the unique user id
+ type: string
+ format: uuid
+```
+
+Can be used in a link like this:
+
+```yaml
+Addresses:
+ href: '/users/{$request.id}/department'
+```
+
+Where the `$request.id` is the value passed in the request to `/users/{id}`. For a `id` value of `10101110`, the generated link would be:
+
+```yaml
+href: '/users/10101110/department'
+```
+
+### Response payload example
+
+```yaml
+Addresses:
+ href: '/users/{$response.uuid}/address'
+```
+
+Where the `$response.uuid` from the example above would yield the target:
+
+
+```yaml
+href: '/users/df71a505-07bc-458a-a5c0-73c0340d1ec7/address'
+```
+
+And the array example:
+
+```yaml
+ColorSelection:
+ href: 'http://colors.my-server.com/colors/{$response.color}'
+```
+
+Would produce the following links:
+
+```yaml
+href: 'http://colors.my-server.com/colors/red'
+href: 'http://colors.my-server.com/colors/green'
+href: 'http://colors.my-server.com/colors/blue'
+```
+
+As with all links, it at the the clients' discretion to follow them, and permissions and the ability to make a successful call to that link is not guaranteed soley by the existance of a relationship.
+
+
+### Example
+
+The example below shows how relationships in the BitBucket API can be represented with the proposed OAI link scheme. This example uses `operationId` values to link responses to possible operations.
+
+```yaml
+paths:
+ /2.0/users/{username}:
+ get:
+ operationId: getUserByName
+ parameters:
+ - name: username
+ type: string
+ in: path
+ required: true
+ responses:
+ 200:
+ description: The User
+ schema:
+ $ref: '#/components/definitions/user'
+ links:
+ userRepositories:
+ $ref: '#/components/links/UserRepositories'
+ /2.0/repositories/{username}:
+ get:
+ operationId: getRepositoriesByOwner
+ parameters:
+ - name: username
+ type: string
+ in: path
+ required: true
+ responses:
+ 200:
+ description: repositories owned by the supplied user
+ schema:
+ type: array
+ items:
+ $ref: '#/components/definitions/repository'
+ links:
+ userRepository:
+ $ref: '#/components/links/UserRepository'
+ /2.0/repositories/{username}/{slug}:
+ get:
+ operationId: getRepository
+ parameters:
+ - name: username
+ type: string
+ in: path
+ required: true
+ - name: slug
+ type: string
+ in: path
+ required: true
+ responses:
+ 200:
+ description: The repository
+ schema:
+ $ref: '#/components/definitions/repository'
+ links:
+ repositoryPullRequests:
+ $ref: '#/components/links/RepositoryPullRequests'
+ /2.0/repositories/{username}/{slug}/pullrequests:
+ get:
+ operationId: getPullRequestsByRepository
+ parameters:
+ - name: username
+ type: string
+ in: path
+ required: true
+ - name: slug
+ type: string
+ in: path
+ required: true
+ - name: state
+ type: string
+ in: query
+ enum:
+ - open
+ - merged
+ - declined
+ responses:
+ 200:
+ description: an array of pull request objects
+ schema:
+ type: array
+ items:
+ $ref: '#/components/definitions/pullrequest'
+ /2.0/repositories/{username}/{slug}/pullrequests/{pid}:
+ get:
+ operationId: getPullRequestsById
+ parameters:
+ - name: username
+ type: string
+ in: path
+ required: true
+ - name: slug
+ type: string
+ in: path
+ required: true
+ - name: pid
+ type: string
+ in: path
+ required: true
+ responses:
+ 200:
+ description: a pull request object
+ schema:
+ $ref: '#/components/definitions/pullrequest'
+ links:
+ $ref: '#/components/links/PullRequestMerge'
+ /2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge:
+ post:
+ operationId: mergePullRequest
+ parameters:
+ - name: username
+ type: string
+ in: path
+ required: true
+ - name: slug
+ type: string
+ in: path
+ required: true
+ - name: pid
+ type: string
+ in: path
+ required: true
+ responses:
+ 204:
+ description: the PR was successfully merged
+components:
+ links:
+ UserRepositories:
+ # returns array of '#/components/definitions/repository'
+ operationId: getRepositoriesByOwner
+ parameters:
+ username: $response.username
+ UserRepository:
+ # returns '#/components/definitions/repository'
+ operationId: getRepository
+ parameters:
+ username: $response.owner.username
+ slug: $response.slug
+ RepositoryPullRequests:
+ # returns '#/components/definitions/pullrequest'
+ operationId: getPullRequestsByRepository
+ params:
+ username: $response.owner.username
+ slug: $response.slug
+ PullRequestMerge:
+ # executes /2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge
+ operationId: mergePullRequest
+ parameters:
+ username: $response.user.username # Should be $response.author.username?
+ slug: $response.repository.slug
+ pid: $response.id
+ definitions:
+ user:
+ type: object
+ properties:
+ username:
+ type: string
+ uuid:
+ type: string
+ repository:
+ type: object
+ properties:
+ slug:
+ type: string
+ owner:
+ $ref: '#/components/definitions/user'
+ pullrequest:
+ type: object
+ properties:
+ id:
+ type: integer
+ title:
+ type: string
+ repository:
+ $ref: '#/components/definitions/repository'
+ author:
+ $ref: '#/components/definitions/user'
+```
+
+As references to `operationId` may not be possible (the `operationId` is an optional value), references may also be made through a relative `href`:
+
+```yaml
+components:
+ links:
+ UserRepositories:
+ # returns array of '#/components/definitions/repository'
+ href: '/2.0/repositories/{$response.username}'
+```
+
+or an absolute `href`:
+
+```yaml
+components:
+ links:
+ UserRepositories:
+ # returns array of '#/components/definitions/repository'
+ href: 'https://na2.gigantic-server.com/2.0/repositories/{$response.username}'
+```
+
+
+### Link Parameters
+Using the `operationId` to reference an operation in the definition has many benefits, including the ability to define media-type options, security requirements, response and error payloads. Many operations require parameters to be passed, and these may be dynamic depending on the response itself.
+
+To specify parameters required by the operation, we can use a **Link Parameters Object**. This object contains parameter names along with static or dynamic valus:
+
+```yaml
+paths:
+ /user/{username}: # ...
+ /user/{username}/commits:
+ get:
+ operationId: userCommitHistory
+ parameters:
+ - name: username
+ in: path
+ type: string
+ required: true
+ - name: page
+ type: integer
+ format: int32
+ required: true
+ responses: { ... }
+components:
+ links:
+ UserCommitHistory:
+ operationId: userCommitHistory
+ parameters:
+ username: $response.user.username
+ page: 0
+```
+
+In the above, the link for `UserCommitHistory` points to the operation `getUserCommitHistory`, and passes the `username` value from the response payload as well as the static scalar value `0`.
+
#### Header Object
Field Name | Type | Description