This PEP proposes a multi-request workflow, which at a high level involves these steps:
Like PEP 691, this PEP proposes that all requests and responses from this upload API will have a
standard content type that describes what the content is, what version of the API it represents,
and what serialization format has been used.
This standard request content type applies to all requests except for requests to execute
a file upload mechanism, which will be specified by the documentation for that mechanism.
The structure of the Content-Type header for all other requests is:
application/vnd.pypi.upload.$version+$format
Since minor API version differences should never be disruptive, only the major version is included
in the content type; the version number is prefixed with a v.
The major API version specified in the .meta.api-version JSON key of client requests
MUST match the Content-Type header for major version.
Unlike PEP 691, this PEP does not change the existing legacy 1.0 upload API in any way,
so servers are required to host the new API described in this PEP at a different endpoint than the
existing upload API.
Since JSON is the only defined request format defined in this PEP, all non-file-upload requests
defined in this PEP MUST include a Content-Type header value of:
application/vnd.pypi.upload.v2+json.
Similar to PEP 691, this PEP also standardizes on using server-driven content negotiation to allow clients
to request different versions or serialization formats, which includes the format part of the content
type. However, since this PEP expects the existing legacy 1.0 upload API to exist at a different
endpoint, and this PEP currently only provides for JSON serialization, this mechanism is not particularly
useful. Clients only have a single version and serialization they can request. However clients SHOULD be
prepared to handle content negotiation gracefully in the case that additional formats or versions are added in
the future.
Servers MUST NOT advertise support for API versions beyond those defined in approved PEPs.
Any new versions or formats require standardization through a new PEP.
Unless otherwise specified, all HTTP requests and responses in this document are assumed to include
the HTTP header:
Content-Type: application/vnd.pypi.upload.v2+json
All endpoints in this specification MUST use standard HTTP authentication
mechanisms as defined in RFC 7235.
Authentication follows the standard HTTP pattern:
- Servers use the
WWW-Authenticate response header when authentication is required
- Clients provide credentials via the
Authorization request header
401 Unauthorized indicates missing or invalid authentication
403 Forbidden indicates insufficient permissions
The specific authentication schemes (e.g., Bearer, Basic, Digest)
are determined by the index operator.
Authentication establishes the principal making a request. Authorization determines whether that principal
may act on a particular session. All session endpoints defined in this specification (i.e. the URLs returned
under the links key when a publishing session or file upload
session is created) MUST be authorized against the project’s upload
permissions. Specifically, a server MUST verify, contemporaneously on each request, that the
authenticated principal is currently authorized to upload to the project named by the session, and MUST
respond with 403 Forbidden if it is not.
Because this check is performed independently on each request, a session is not tied to the exact
credentials that created it:
- A principal that is granted upload permission after a session is opened may immediately participate in that
session.
- A principal whose upload permission is revoked while a session is open MUST be denied with a
403 Forbidden on any subsequent request, even if that principal created the session.
This denial is evaluated per request and is not “sticky”: if a principal’s permission is later restored, its
subsequent requests are authorized again. An index MAY apply a stricter policy, but this specification
does not require one.
Servers MUST perform this authorization check on at least every request that creates, modifies, completes,
extends, cancels, or publishes a publishing session or file upload session. For upload mechanisms that
transfer a file across more than one request (for example, chunked or multipart mechanisms), servers
SHOULD authorize each such request.
The unguessable stage preview URL is a separate capability and is deliberately not
governed by this authorization check; it grants read-only preview access to any client that holds the token,
so that (for example) a CI job can install-test a staged release without project upload credentials.
Unless otherwise specified, all error (4xx and 5xx) responses from the server MUST use the RFC 9457
(Problem Details for HTTP APIs) format. In particular, the server MUST use the “Problem Details JSON
Object” defined in Section 3 and SHOULD use the application/problem+json media
type in its responses.
Clients in general should be prepared to handle HTTP response error status codes which SHOULD contain payloads like
the following, although note that the details are index-specific, as long as they conform to RFC 9457. By way
of example, PyPI could return the following error body:
{
"type": "https://docs.pypi.org/api/errors/error-types#invalid-filename",
"status": 400,
"title": "The artifact used an invalid wheel file name format",
"details": "See https://packaging.python.org/en/latest/specifications/binary-distribution-format/",
"meta": {
"api-version": "2.0"
},
"errors": [
{
"source": "...",
"message": "..."
}
]
}
RFC 9457 defines type, status, title, and details. The meta and errors keys are
“extension members”, defined in Section 3.2. The index SHOULD include these
extension members.
meta- The same request/response metadata structure as defined in the Publishing Session description.
errors- An array of specific errors, each of which contains a
source key, which is a string that
indicates what the source of the error is, and a message key for that specific error.
The message and source strings do not have any specific meaning, and are intended for human
interpretation to aid in diagnosing underlying issue.
Some responses may return more specific HTTP status codes as described in the text below.
A release starts by creating a new publishing session. To create the session, a client submits a
POST request to the root URL like:
{
"meta": {
"api-version": "2.0"
},
"name": "foo",
"version": "1.0",
}
The request includes the following top-level keys:
meta (required)- Describes information about the payload itself. Currently, the only required sub-key is
api-version the value of which must be the string "2.0". Optional sub-keys can define
index-specific behavior.
name (required)- The name of the project that this session is attempting to release a new version of. The name
MUST conform to the standard package name format
and the server MUST normalize the name.
version (required)- The version of the project that this session is attempting to add files to. The version string
MUST conform to the packaging version specification.
Upon successful session creation, the server returns a 201 Created response. The response MUST also
include a Location header containing the same URL as the links.session
key in the response body.
If a session is created for a project which has no previous release, then the index MAY reserve the
project name before the session is published, however it MUST NOT be possible to navigate to that project
using the “regular” (i.e. unstaged) access protocols, until the stage is published.
If this first-release stage gets canceled, then the index SHOULD delete the project record, as if it were
never uploaded.
A publishing session is not bound to the specific credentials that created it. Instead, every request
against the session MUST be performed by an authenticated principal that is authorized to upload to the
project at the time of that request, as described in Authentication and Authorization. A request from a principal that
is not, or is no longer, so authorized MUST receive a 403 Forbidden.
For a first-release session on a project that does not yet exist, there are no existing project upload
permissions to evaluate; the index instead authorizes the request according to its own name-registration
policy, and SHOULD treat the creating principal (and, where applicable, an organization it acts on behalf
of) as authorized for the lifetime of the session.
A publishing session is always in exactly one of the following states, reported by the status key of the
session status response:
The textual description of each state and a complete transition table follow.
open- The session is accepting changes. Files can be uploaded, replaced,
and deleted; the session can be previewed and extended; and it can be
published or canceled. A newly created session starts in this state.
processing- The client has requested publication and the server accepted the request for deferred processing,
returning a
202 Accepted (see Complete a Publishing Session). The session is no longer
accepting changes while the server validates and processes it. This is a transitional state; the client
polls the session status until it resolves to published or
error.
published (terminal)- The session’s files have been published and are publicly available. No further changes are possible.
error- The most recent deferred publish attempt failed. The session is fully editable again – it permits
exactly the same operations as
open, and differs from open only in that it records that the last
publish attempt failed. The human-readable reason MUST be reported in the session’s notices (and,
where the failure is attributable to a particular file, in that file’s notices). From this state the
client can address the problem and publish again, or cancel the session.
canceled (terminal)- The session was canceled and its staged data discarded. No further changes are possible.
Both open and error are editable states that permit the identical set of operations; a client MUST
NOT treat an error session as closed or read-only. The only difference between them is that error
additionally records that the previous deferred publish request failed.
Because published and canceled are terminal, reaching either one frees the name-version pair so that a
subsequent session may be created for it, for example, to add wheels
for additional platforms to an already-published release.
The transitions between these states are:
| From |
Event |
To |
| (none) |
Session created |
open |
open |
A file is uploaded, replaced, or deleted |
open |
open |
Publish request completed immediately (201 Created) |
published |
open |
Publish request accepted for deferred processing (202 Accepted) |
processing |
open or error |
Publish request fails synchronously |
unchanged (the error is returned to the caller) |
open or error |
Session canceled (DELETE) |
canceled |
processing |
Deferred processing succeeds |
published |
processing |
Deferred processing fails |
error |
processing |
Cancellation requested |
rejected with 409 Conflict (see Publishing Session Cancellation) |
error |
A file is uploaded, replaced, or deleted |
error |
error |
Publish retried |
processing or published |
A synchronous publish failure (i.e. one the server determines within the publish request itself) is returned
to the caller as an error response and leaves the session in its current editable
state (open stays open; error stays error). The error state is reached only when a
publish that was accepted for deferred processing subsequently fails, because in that case the failure cannot
be returned to the caller directly and the client discovers it by polling.
To complete a session and publish the files that have been included in it, a client issues a
POST request to the publish link
given in the session creation response body.
The request looks like:
{
"meta": {
"api-version": "2.0"
}
}
If the server is able to immediately complete the publishing session, it may do so and return a 201
Created response, moving the session to the terminal status
published. If it is unable to immediately complete the publishing session (for instance, if it needs to
do validation that may take longer than reasonable in a single HTTP request), then it may return a 202
Accepted response and move the session to the processing state.
The server MUST include a Location header in the response pointing back to the Publishing
Session status URL, which can be used to query the current session status. If
the server returned a 202 Accepted, polling that URL can be used to watch for the session status to
change: deferred processing resolves to either published on success or error on failure. When it
resolves to error, the session remains editable and the reason is reported in the session’s notices,
as described in Publishing Session States.
A publish attempt that fails synchronously (i.e. within the publish request itself) is returned to the
client as an error response and leaves the session in its current editable state; it
does not move the session to error.
Publishing a session is atomic with respect to the release’s filename namespace. Because published artifacts
are immutable, the index MUST guarantee that it never publishes two files with the same name for the same
release, even in the presence of concurrent uploads arriving through this API or the legacy API.
The point-in-time conflict check performed when a file upload session is created
is best-effort: it reflects the published state at the moment of that request and does not guarantee the
file will still be conflict-free at publish time, since the published state of the release can change while a
session is open. For example, a file with the same name may be published through the legacy API, or through a
subsequent session for the same, already-published name and version. The authoritative conflict check
is therefore performed atomically at publish time.
Filename reservation. When a client requests publication, the server MUST atomically reserve the
filenames of all files in the session within the target release, and hold that reservation for the duration of
the publish:
- While the reservation is held, any other attempt to upload a file with one of those filenames to the same
release – whether through this API or the legacy API – MUST be rejected with a
409 Conflict,
exactly as if the file were already published. The index MUST enforce this regardless of which upload
path the conflicting request arrives through; this is a requirement on the index’s shared published-filename
namespace and does not otherwise modify the legacy API.
- The reservation governs conflict detection only; the reserved files remain staged
and MUST NOT become publicly visible until the publish succeeds.
- If the publish succeeds, the reservation converts to permanent publication. If it fails – synchronously,
leaving the session editable, or during deferred
processing, moving it to the error state – the
server MUST release the reservation, making those filenames available again.
A still-open session does not reserve its filenames; the reservation is acquired only when publication
is requested. For an immediate (201 Created) publish the reservation is held only for the duration of the
single request and is effectively unobservable. The requirement is meaningful mainly for deferred (202
Accepted then processing) publishes, where there is a real window between the index validating one staged
artifact and committing the rest.
This closes that window at a deliberate, conservative cost: a concurrent upload MAY receive a 409
Conflict during a publish that ultimately fails, and then succeed on retry once the reservation is released.
The index never publishes two files with the same name, at the cost of occasionally rejecting a concurrent
upload that a later retry would allow.
Reporting a publish-time conflict. When the index detects a conflict while publishing – whether a
filename collision as above, or another precondition that held when the session was created but no longer
holds, such as an exhausted quota or a revoked permission – it reports the failure according to the
publishing session state machine:
- If the server is completing the publish synchronously, it MUST return an error response – a
409 Conflict for a filename collision – identifying the conflicting file(s), and
leave the session in its current editable state.
- If the server accepted the publish for deferred processing and detects the conflict during
processing,
it MUST move the session to the error state and report the conflicting file(s) in the session’s
notices (and, where the failure is attributable to a particular file, in that file’s notices).
In either case the client may delete or replace the offending file, or otherwise resolve the conflict, and
publish again, or cancel the session.
To cancel a publishing session, a client issues a DELETE request to the session link given in the session creation response body.
The server then marks the session as canceled and SHOULD purge any data that was uploaded as part of
that session. Once that data is purged, the session’s action and data-bearing URLs – links.upload,
links.publish, links.extend, links.stage, and the individual file URLs – SHOULD become
unavailable and MAY return 404 Not Found. The session status URL (links.session) is instead
retained as described in Session Status Retention: it continues to report the canceled status
for an index-specific period before it too MAY return 404 Not Found.
Cancellation is only permitted while the session is open or in the error state. If the session is in the processing state (i.e. because a deferred
publishing request is already being processed) the server MUST reject the cancellation with a 409
Conflict, since publication may already be in progress. The client can instead wait for processing to
resolve; if it resolves to error, the session can then be canceled.
To prevent dangling sessions, servers may also choose to cancel timed-out sessions on their own
accord. It is recommended that servers expunge their sessions after no less than a week, but each
server may choose their own schedule. Servers MAY support client-directed session
extensions.
At any time, a client can query the status of a session by issuing a GET request to the URL given in the
links.session URL (also provided in the session creation response’s Location header).
The server will respond to this GET request with the same publishing session creation response, that they got when they initially created the publishing session, except with
any changes to status, expires-at, or files reflected.
A session status URL is not guaranteed to remain valid indefinitely. Once a session reaches a terminal state
– published or canceled – the server SHOULD continue to serve its status URL, reporting the terminal status, for an index-specific retention period, so
that clients can reliably observe the final outcome of a session they did not watch to completion. After that
retention period elapses, the server MAY return 404 Not Found for the status URL. The length of the
retention period is left to the index, but SHOULD be long enough to let a client that initiated or
contributed to the session learn its outcome.
This retention applies only to the session status; the data-bearing and action URLs for a terminated session
(for example links.stage and the individual file URLs) may become unavailable as soon as their underlying
data is no longer needed, as described for cancellation.
Clients MUST be prepared for a session status URL to return 404 Not Found once the session has
terminated and its retention period has elapsed. A 404 on a previously valid session status URL is not in
itself an error; clients SHOULD treat it as indicating that the session no longer exists. Note that once a
terminated session has been purged, a request to create a new session for
the same name and version will succeed with a 201 Created rather than returning the 409
Conflict that a still-live session would have produced.
Servers MAY allow clients to extend sessions, but the overall lifetime and number of extensions
allowed is left to the server. To extend a session, a client issues a POST request to the
links.extend URL. If the server does not support session extensions,
the links.extend key will not be present in the response.
The request looks like:
{
"meta": {
"api-version": "2.0"
},
"extend-for": 3600
}
The number of seconds specified is just a suggestion to the server for the number of additional seconds to
extend the current session. For example, if the client wants to extend the current session for another hour,
extend-for would be 3600. Upon successful extension, the server will respond with the same
publishing session creation response body that they got when they
initially created the publishing session, except with any changes to status, expires-at, or files
reflected.
If the server refuses to extend the session for the requested number of seconds, it MUST still return a
success response, and the expires-at key will simply reflect the current expiration time of the session.
Indexes SHOULD support preview stages so that uploaded files can be live tested
before publishing. E.g. a CI client could perform installation tests using pre-published wheels to ensure
that their new release works as expected before they publish the release publicly.
Indexes advertise their support for staged previews by returning two key pieces of information in their
response to publishing session creation. Indexes which don’t support
staged previews MUST NOT include these in their responses.
The session-token is a short token which could be used as a convenience for installation tool UX. For
example, pip could add a --stage $SESSION_TOKEN flag as a convenience for installing from a staged
preview. The links.stage key gives the full URL to the stage, which can be used with installers today,
e.g. pip install --extra-index-url $STAGE_URL. Both the session token and URL MUST be
cryptographically unguessable, but the algorithm for generating the token is left to the index. The stage URL
MUST be calculable from the session token, using a format documented by the index, but the exact format of
the URL is also left to the index.
After creating a publishing session, the upload endpoint from the response’s session links mapping is used to begin the upload of new files into that session. Clients
MUST use the provided upload URL and MUST NOT assume there is any pattern or commonality to those
URLs from one session to the next.
To initiate a file upload, a client first sends a POST request to the upload URL.
The request looks like:
{
"meta": {
"api-version": "2.0"
},
"filename": "foo-1.0.tar.gz",
"size": 1000,
"hashes": {"sha256": "...", "blake2b": "..."},
"mechanism": "http-post-bytes"
}
Besides the standard meta key, the request JSON has the following additional keys:
filename (required)- The name of the file being uploaded. The filename MUST conform to either the
source distribution file name specification
or the binary distribution file name convention.
Indexes SHOULD validate these file names at the time of the request, returning a
400 Bad Request
error code and an RFC 9457 style error body, as described in the Errors section when the
file names do not conform.
size (required)- The final total size in bytes of the file being uploaded.
hashes (required)- A mapping of hash names to hex-encoded digests. Each of these digests are the checksums of the
file being uploaded when hashed by the algorithm identified in the name.
By default, any hash algorithm available in hashlib can be used as a key for the hashes
dictionary . At least one secure algorithm from hashlib.algorithms_guaranteed
MUST always be included. This PEP specifically recommends sha256.
Multiple hashes may be passed at a time, but all hashes provided MUST be valid for the file.
mechanism (required)- The file-upload mechanisms the client intends to use for this file.
This mechanism SHOULD be chosen from the list of mechanisms advertised in the
publishing session creation response body.
A client MAY send a mechanism that is not advertised in cases where server operators have
documented a new or upcoming mechanism that is available for use on a “pre-release” basis.
Servers MAY use the data provided in this request to do some sanity checking prior to allowing
the file to be uploaded. These checks may include, but are not limited to:
- checking if the
filename already exists in a published release;
- checking if the
size would exceed any project or file quota.
A publishing session MAY be created for a name and version that has already been published, for
example to add wheels for additional platforms to an existing release. However, because published artifacts
are immutable, if the filename in this request matches a file that has already been published for this
release, the server MUST reject the request with a 409 Conflict and MUST NOT overwrite the
published file. This check is best-effort and reflects the published state at the time of the request; the
authoritative, atomic conflict check is performed at publish time, as described in
Atomic Publication and Conflicts.
If the server determines that upload should proceed, it will return a 202 Accepted response, with the
response body below. The status of the publishing session will also
include the filename in the files mapping. If the server cannot proceed with an upload because the
mechanism supplied by the client is not supported it MUST return a 422 Unprocessable Content. The
server MAY allow parallel uploads of files, but is not required to. If the server determines the upload
cannot proceed, it MUST return a 409 Conflict.
The successful response includes the following:
{
"meta": {
"api-version": "2.0"
},
"links": {
"file-upload-session": "...",
"complete": "...",
"extend": "..."
},
"status": "pending",
"expires-at": "2030-08-01T13:00:00Z",
"mechanism": {
"identifier": "http-post-bytes",
"file_url": "...",
"attestations_url": "..."
}
}
A Retry-After response header MUST be present to indicate to clients when they should next poll for an
updated status.
Besides the meta key, which has the same format as the request JSON, the success response has
the following keys:
links- A dictionary mapping keys to URLs related to this session,
the details of which are provided below.
status- A string with valid values
pending, processing, complete, error, and canceled
indicating the current state of the file upload session.
expires-at- An RFC 3339 formatted timestamp string representing when the server will expire this file upload
session. This string MUST represent a UTC timestamp using the “Zulu” (i.e.
Z) marker,
and use only whole seconds (i.e. no fractional seconds). The session SHOULD remain active
until at least this time unless the client cancels or completes it. Servers MAY choose to
extend this expiration time, but should never move it earlier.
mechanism- A mapping containing the necessary details for the supported mechanism as negotiated by the client and
server. This mapping MUST contain a key
identifier which maps to the identifier string for the
chosen file upload mechanism.
A file upload session is always in exactly one of the following states, reported by the status
key of the file upload session status response. The same
value is reflected for the file in the files mapping of the publishing session status.
The textual description of each state and a complete transition table follow.
pending- The file upload session has been created and the negotiated upload mechanism is being executed; the file’s bytes are in transit or not yet fully transferred.
A newly created session starts in this state and remains in it until the client completes or cancels the upload. A file
whose upload is still
pending cannot be replaced.
processing- The client has requested completion and the server accepted the request for deferred processing, returning
a
202 Accepted (see Complete a File Upload Session). This is a transitional state; the client
polls the file upload session status, respecting the Retry-After
header, until it resolves to complete or error.
complete- The file has been fully uploaded, validated, and accepted into the publishing session. The file can still
be deleted, which removes it from the publishing session and
moves this session to
canceled.
error- The upload failed and the file is not in a usable state. Unlike a publishing session in the
error state, a file upload session cannot be repaired in place: the client
MUST cancel or delete the file and, if it still wants to
upload it, begin an entirely new file upload session. A file upload session enters
error whenever a
completion attempt fails – whether the server detects the failure synchronously within the complete
request, or asynchronously while the session is processing.
canceled (terminal)- The session was canceled (an in-progress upload) or its completed file was deleted. The session resource
and its associated upload mechanisms MUST NOT be assumed reusable; recovering or replacing the file
requires a new file upload session.
Only canceled is terminal. Both complete and error still permit a DELETE (which moves the
session to canceled); from error, deletion is the only forward action.
The transitions between these states are:
| From |
Event |
To |
| (none) |
File upload session created (202 Accepted) |
pending |
pending |
Upload mechanism executes (bytes transferred) |
pending |
pending |
Completion request completed immediately (201 Created) |
complete |
pending |
Completion request accepted for deferred processing (202 Accepted) |
processing |
pending |
Completion request fails synchronously |
error |
pending |
Cancellation requested (DELETE) |
canceled |
processing |
Deferred processing succeeds |
complete |
processing |
Deferred processing fails |
error |
processing |
Cancellation requested |
rejected with 409 Conflict (see Cancellation and Deletion) |
complete |
File deleted (DELETE) |
canceled |
error |
File deleted (DELETE) |
canceled |
Unlike a publishing session, where a synchronous publish failure leaves the session editable and only a
deferred failure reaches the error state, a file upload session treats any completion failure as
unrecoverable for that file, because a partially or incorrectly uploaded file cannot be edited in place.
Both a synchronous and a deferred completion failure therefore move the session to error, from which the
client deletes the file and starts over.
To complete a file upload session, which indicates that the file upload mechanism has been executed
and did not produce an error, a client issues a POST to the complete link in the file upload session creation response body.
The request looks like:
{
"meta": {
"api-version": "2.0"
}
}
If the server is able to immediately complete the file upload session, it may do so and return a 201
Created response and set the status of the file upload session to complete. If it is unable to
immediately complete the file upload session (for instance, if it needs to do validation that may take longer
than reasonable in a single HTTP request), then it may return a 202 Accepted response and set the status
of the file upload session to processing.
In either case, the server should include a Location header pointing back to the file upload session
status URL.
Servers MUST allow clients to poll the file upload session status URL to watch for the status to change.
If the server responds with a 202 Accepted, clients may poll the file upload session status URL to watch
for the status to change. Clients SHOULD respect the Retry-After header value of the file upload
session status response.
If a completion attempt fails – synchronously (in which case the server also returns an error response) or asynchronously while the session is processing – the session moves to the
error state, from which the client must cancel or delete the file and start a new file upload session to retry.
A client can cancel an in-progress file upload session, or delete a file that has been completely uploaded.
In both cases, the client performs this by issuing a DELETE request to the links.file-upload-session
URL from the file upload session creation response of the file they want
to delete.
A successful deletion request MUST respond with a 204 No Content.
A DELETE is permitted while the session is pending (canceling an in-progress upload), complete
(deleting an uploaded file), or error (discarding a failed upload). If the session is in the
processing state – that is, a deferred completion is already underway – the server MUST reject the
DELETE with a 409 Conflict, since the outcome is already being decided. The client can instead wait
for processing to resolve and then delete the file if needed.
Once canceled or deleted, a client MUST NOT assume that the previous file upload session resource or
associated file upload mechanisms can be reused.
To replace a session file, the file upload MUST have been previously completed, canceled, or
deleted. A file whose upload is still in-progress cannot be replaced; if a client attempts to do so,
the server MUST return a 409 Conflict.
To replace a session file, clients should cancel and delete the in-progress upload first. After this, the new file upload can be initiated by beginning the
entire file upload sequence over again. This means providing the metadata
request again to retrieve a new upload resource URL. Clients MUST NOT assume that the previous upload
resource URL can be reused after deletion.
The client can query status of the file upload session by issuing a GET request to the
links.file-upload-session URL from the file upload session creation response. The server responds to this request with the same payload as the file upload
session creation response, except with any changes status and expires-at reflected.
A file upload session has no existence independent of the publishing session it belongs to, and its status URL
is retained accordingly. While the parent publishing session is in a non-terminal state, the server
SHOULD keep each of its file upload session status URLs valid, reporting the file upload session’s current
status – including a terminal canceled – so that a client can observe the outcome of any file it
uploaded. Once the parent publishing session itself terminates, its file upload session URLs are retained no
longer than the parent’s own status URL and MAY return 404 Not
Found thereafter. As with cancellation, the data-bearing and mechanism portions of these URLs may become
unavailable as soon as the underlying file data is purged, independent of the status URL.
Servers MAY allow clients to extend file upload sessions, but the overall lifetime and number of
extensions allowed is left to the server. To extend a file upload session, a client issues a POST request
to the extend link from the file upload session creation response. If the server does not support file upload session extensions,
the links.extend key will not be present in the response.
The request looks like:
{
"meta": {
"api-version": "2.0"
},
"extend-for": 3600
}
The number of seconds specified is just a suggestion to the server for the number of additional seconds to
extend the current file upload session. For example, if the client wants to extend session for another hour,
extend-for would be 3600. Upon successful extension, the server will respond with the same file
upload session creation response body that they got when they initially
created the publishing session, except with any changes to status or expires-at reflected.
If the server refuses to extend the session for the requested number of seconds, it MUST still return a
success response, and the expires-at key will simply reflect the current expiration time of the session.