# Upload Product Document

Attaches a PDF to a product, such as the MSDS (safety data sheet) or a certificate. A document is stored once on the product and kept for the customs paperwork carriers request on its export shipments.

PDF only, at most 10 MB. A product can hold several documents.

Endpoint: POST /api/fulfilment/product-documents/{sku}
Version: 1.0.0
Security: BearerAuth, OAuth2

## Security:

  - `BearerAuth` (unknown)
    http bearer

  - `OAuth2` (unknown)
    oauth2

## Path parameters:

  - `sku` (string, required)
    The product SKU.

## Request fields (application/json):

  - `content_base64` (string, required)
    The PDF, Base64 encoded. PDF only, at most 10 MB once decoded.

  - `document_type` (string, required)
    msds, certificate or other.
    Enum: "msds", "certificate", "other"

  - `file_name` (string)
    File name shown in QuiqDash. Defaults to the document type.

## Response 200:

  - `200` (unknown)
    Success response

## Response 200 fields (application/json):

  - `created_at` (string, required)
    When the document was uploaded.

  - `document_type` (string, required)
    msds, certificate or other.

  - `file_name` (string, required)
    File name.

  - `file_size` (integer, required)
    Size in bytes.

  - `id` (string, required)
    Quiqup's id for the document.

  - `url` (string, required)
    Link to download the PDF. It expires after 24 hours; list the documents again for a new one.

## Response 4XX:

  - `4XX` (unknown)
    Error response. See [Error responses](/docs/errors).

## Response 4XX fields (application/json):

  - `code` (string, required)
    The error code. It matches the HTTP status: invalid_argument and failed_precondition are 400, unauthenticated 401, permission_denied 403, not_found 404, already_exists 409, internal 500 and unavailable 503.
    Enum: "canceled", "unknown", "invalid_argument", "deadline_exceeded", "not_found", "already_exists", "permission_denied", "resource_exhausted", "failed_precondition", "aborted", "out_of_range", "unimplemented", "internal", "unavailable", "data_loss", "unauthenticated"

  - `details` (object)
    More about the error. Can be null.

  - `details.field_diffs` (array)
    When an inbound is refused because your product data and the warehouse's disagree, one entry per disagreement.

  - `details.field_diffs.field` (string)
    What disagrees, for example barcode_mismatch.

  - `details.field_diffs.ours` (string)
    The value Quiqup holds for the product.

  - `details.field_diffs.sku` (string)
    The SKU.

  - `details.field_diffs.warehouse` (string)
    The value the warehouse holds.

  - `details.fields` (array)
    For input errors, one entry per field that failed.

  - `details.fields.field` (string)
    The field that failed. Request validation names it by its path in the request, for example ShippingAddress.Phone or Items[0].UnitPrice, which is not always the JSON name.

  - `details.fields.message` (string)
    What was wrong. Request validation gives the rule that failed, for example required.

  - `details.reason` (string)
    A stable identifier for some failures, safe to branch on.

  - `details.request_id` (string)
    Identifies the request. Quote it when you contact support.

  - `details.type` (string)
    The kind of failure.
    Enum: "input", "not_found", "unauthorized", "forbidden", "integration", "internal"

  - `message` (string, required)
    A sentence describing the error.

## Response default:

  - `default` (unknown)
    Error response. See [Error responses](/docs/errors).

## Response default fields (application/json):

  - `code` (string, required)
    The error code. It matches the HTTP status: invalid_argument and failed_precondition are 400, unauthenticated 401, permission_denied 403, not_found 404, already_exists 409, internal 500 and unavailable 503.
    Enum: "canceled", "unknown", "invalid_argument", "deadline_exceeded", "not_found", "already_exists", "permission_denied", "resource_exhausted", "failed_precondition", "aborted", "out_of_range", "unimplemented", "internal", "unavailable", "data_loss", "unauthenticated"

  - `details` (object)
    More about the error. Can be null.

  - `details.field_diffs` (array)
    When an inbound is refused because your product data and the warehouse's disagree, one entry per disagreement.

  - `details.field_diffs.field` (string)
    What disagrees, for example barcode_mismatch.

  - `details.field_diffs.ours` (string)
    The value Quiqup holds for the product.

  - `details.field_diffs.sku` (string)
    The SKU.

  - `details.field_diffs.warehouse` (string)
    The value the warehouse holds.

  - `details.fields` (array)
    For input errors, one entry per field that failed.

  - `details.fields.field` (string)
    The field that failed. Request validation names it by its path in the request, for example ShippingAddress.Phone or Items[0].UnitPrice, which is not always the JSON name.

  - `details.fields.message` (string)
    What was wrong. Request validation gives the rule that failed, for example required.

  - `details.reason` (string)
    A stable identifier for some failures, safe to branch on.

  - `details.request_id` (string)
    Identifies the request. Quote it when you contact support.

  - `details.type` (string)
    The kind of failure.
    Enum: "input", "not_found", "unauthorized", "forbidden", "integration", "internal"

  - `message` (string, required)
    A sentence describing the error.

