From d07b52f22fba71bff19c9a730186acea002f0254 Mon Sep 17 00:00:00 2001
From: Yusef Napora <yusef@protocol.ai>
Date: Tue, 24 May 2022 14:39:25 -0400
Subject: [PATCH] feat: use application/vnd.ipld.car as preferred content-type

---
 packages/api/src/routes/metaplex-upload.js    |  2 +-
 packages/api/src/routes/nfts-upload.js        |  4 +-
 packages/api/src/utils/car.js                 |  6 +-
 .../api/test/nfts-metaplex-upload.spec.js     | 14 ++--
 packages/api/test/nfts-upload.spec.js         | 80 ++++++++++---------
 packages/client/src/lib.js                    |  2 +-
 packages/client/test/lib.spec.js              |  2 +-
 packages/client/test/service.js               |  5 +-
 packages/website/lib/mock_files.js            | 52 ++++++------
 .../pages/docs/how-to/mint-custom-metadata.md |  2 +-
 packages/website/public/schema.yml            |  9 ++-
 11 files changed, 97 insertions(+), 81 deletions(-)

diff --git a/packages/api/src/routes/metaplex-upload.js b/packages/api/src/routes/metaplex-upload.js
index e59812c0fd..851944c607 100644
--- a/packages/api/src/routes/metaplex-upload.js
+++ b/packages/api/src/routes/metaplex-upload.js
@@ -52,7 +52,7 @@ export async function metaplexUpload(event, ctx) {
       user,
       key,
       car: blob,
-      mimeType: 'application/car',
+      mimeType: 'application/vnd.ipld.car',
       files: [],
       structure: 'Unknown',
       meta,
diff --git a/packages/api/src/routes/nfts-upload.js b/packages/api/src/routes/nfts-upload.js
index 85fb854782..b2f5f8937a 100644
--- a/packages/api/src/routes/nfts-upload.js
+++ b/packages/api/src/routes/nfts-upload.js
@@ -67,7 +67,9 @@ export async function nftUpload(event, ctx) {
       throw new HTTPError('empty payload', 400)
     }
 
-    const isCar = contentType.includes('application/car')
+    const isCar =
+      contentType.includes('application/car') ||
+      contentType.includes('application/vnd.ipld.car')
     /** @type {'Car'|'Blob'} */
     let uploadType
     /** @type {DagStructure} */
diff --git a/packages/api/src/utils/car.js b/packages/api/src/utils/car.js
index ce1b8dc5fc..c7d331b673 100644
--- a/packages/api/src/utils/car.js
+++ b/packages/api/src/utils/car.js
@@ -8,7 +8,7 @@ import { CarWriter } from '@ipld/car'
 /**
  * @param {CID[]} roots
  * @param {AsyncIterable<Block>|Iterable<Block>} blocks
- * @returns {Promise<Blob & { type: 'application/car' }>}
+ * @returns {Promise<Blob & { type: 'application/vnd.ipld.car' }>}
  */
 export const encode = async (roots, blocks) => {
   const { out, writer } = CarWriter.create(roots)
@@ -22,9 +22,9 @@ export const encode = async (roots, blocks) => {
     parts.push(part)
   }
 
-  return /** @type {Blob & {type: 'application/car'}} */ (
+  return /** @type {Blob & {type: 'application/vnd.ipld.car'}} */ (
     new Blob(parts, {
-      type: 'application/car',
+      type: 'application/vnd.ipld.car',
     })
   )
 }
diff --git a/packages/api/test/nfts-metaplex-upload.spec.js b/packages/api/test/nfts-metaplex-upload.spec.js
index f9432cab11..0943e1b02b 100644
--- a/packages/api/test/nfts-metaplex-upload.spec.js
+++ b/packages/api/test/nfts-metaplex-upload.spec.js
@@ -31,7 +31,7 @@ describe('Metaplex Upload', () => {
       method: 'POST',
       headers: {
         'x-web3auth': `Metaplex ${fixture.token}`,
-        'Content-Type': 'application/car',
+        'Content-Type': 'application/vnd.ipld.car',
       },
       body: car,
     })
@@ -43,7 +43,7 @@ describe('Metaplex Upload', () => {
     assert.strictEqual(value.cid, cid, 'Server responded with expected CID')
     assert.strictEqual(
       value.type,
-      'application/car',
+      'application/vnd.ipld.car',
       'type should match blob mime-type'
     )
 
@@ -81,7 +81,7 @@ describe('Metaplex Upload', () => {
       method: 'POST',
       headers: {
         'x-web3auth': `Metaplex ${fixture.token}`,
-        'Content-Type': 'application/car',
+        'Content-Type': 'application/vnd.ipld.car',
       },
       body: car,
     })
@@ -93,7 +93,7 @@ describe('Metaplex Upload', () => {
     assert.strictEqual(value.cid, cid, 'Server responded with expected CID')
     assert.strictEqual(
       value.type,
-      'application/car',
+      'application/vnd.ipld.car',
       'type should match blob mime-type'
     )
 
@@ -134,7 +134,7 @@ describe('Metaplex Upload', () => {
       method: 'POST',
       headers: {
         'x-web3auth': `Metaplex ${alteredToken}`,
-        'Content-Type': 'application/car',
+        'Content-Type': 'application/vnd.ipld.car',
       },
       body: car,
     })
@@ -160,7 +160,7 @@ describe('Metaplex Upload', () => {
       method: 'POST',
       headers: {
         'x-web3auth': `Metaplex ${alteredToken}`,
-        'Content-Type': 'application/car',
+        'Content-Type': 'application/vnd.ipld.car',
       },
       body: car,
     })
@@ -183,7 +183,7 @@ describe('Metaplex Upload', () => {
       method: 'POST',
       headers: {
         'x-web3auth': `Metaplex ${fixture.token}`,
-        'Content-Type': 'application/car',
+        'Content-Type': 'application/vnd.ipld.car',
       },
       body: car,
     })
diff --git a/packages/api/test/nfts-upload.spec.js b/packages/api/test/nfts-upload.spec.js
index 59226b48e2..46dae4692a 100644
--- a/packages/api/test/nfts-upload.spec.js
+++ b/packages/api/test/nfts-upload.spec.js
@@ -152,40 +152,44 @@ describe('NFT Upload ', () => {
   })
 
   it('should upload a single CAR file', async () => {
-    const { root, car } = await createCar('hello world car')
-    // expected CID for the above data
-    const cid = 'bafkreifeqjorwymdmh77ars6tbrtno74gntsdcvqvcycucidebiri2e7qy'
-    assert.strictEqual(root.toString(), cid, 'car file has correct root')
-    const res = await fetch('upload', {
-      method: 'POST',
-      headers: {
-        Authorization: `Bearer ${client.token}`,
-        'Content-Type': 'application/car',
-      },
-      body: car,
-    })
-
-    assert(res, 'Server responded')
-    assert(res.ok, 'Server response ok')
-    const { ok, value } = await res.json()
-    assert(ok, 'Server response payload has `ok` property')
-    assert.strictEqual(value.cid, cid, 'Server responded with expected CID')
-    assert.strictEqual(
-      value.type,
-      'application/car',
-      'type should match blob mime-type'
-    )
+    // check both accepted content-types for CARs
+    const contentTypes = ['application/car', 'application/vnd.ipld.car']
+    for (const contentType of contentTypes) {
+      const { root, car } = await createCar('hello world car')
+      // expected CID for the above data
+      const cid = 'bafkreifeqjorwymdmh77ars6tbrtno74gntsdcvqvcycucidebiri2e7qy'
+      assert.strictEqual(root.toString(), cid, 'car file has correct root')
+      const res = await fetch('upload', {
+        method: 'POST',
+        headers: {
+          Authorization: `Bearer ${client.token}`,
+          'Content-Type': contentType,
+        },
+        body: car,
+      })
+
+      assert(res, 'Server responded')
+      assert(res.ok, 'Server response ok')
+      const { ok, value } = await res.json()
+      assert(ok, 'Server response payload has `ok` property')
+      assert.strictEqual(value.cid, cid, 'Server responded with expected CID')
+      assert.strictEqual(
+        value.type,
+        contentType,
+        'type should match request mime-type'
+      )
 
-    const { data } = await rawClient
-      .from('upload')
-      .select('*, content(*)')
-      .match({ source_cid: cid, user_id: client.userId })
-      .single()
+      const { data } = await rawClient
+        .from('upload')
+        .select('*, content(*)')
+        .match({ source_cid: cid, user_id: client.userId })
+        .single()
 
-    // @ts-ignore
-    assert.equal(data.source_cid, cid)
-    assert.equal(data.deleted_at, null)
-    assert.equal(data.content.dag_size, 15, 'correct dag size')
+      // @ts-ignore
+      assert.equal(data.source_cid, cid)
+      assert.equal(data.deleted_at, null)
+      assert.equal(data.content.dag_size, 15, 'correct dag size')
+    }
   })
 
   it('should allow a CAR with unsupported hash function', async () => {
@@ -207,9 +211,9 @@ describe('NFT Upload ', () => {
       method: 'POST',
       headers: {
         Authorization: `Bearer ${client.token}`,
-        'Content-Type': 'application/car',
+        'Content-Type': 'application/vnd.ipld.car',
       },
-      body: new Blob(carBytes, { type: 'application/car' }),
+      body: new Blob(carBytes, { type: 'application/vnd.ipld.car' }),
     })
 
     assert(res, 'Server responded')
@@ -223,7 +227,7 @@ describe('NFT Upload ', () => {
     )
     assert.strictEqual(
       value.type,
-      'application/car',
+      'application/vnd.ipld.car',
       'type should match blob mime-type'
     )
   })
@@ -247,7 +251,7 @@ describe('NFT Upload ', () => {
       method: 'POST',
       headers: {
         Authorization: `Bearer ${client.token}`,
-        'Content-Type': 'application/car',
+        'Content-Type': 'application/vnd.ipld.car',
       },
       body: new Blob(carBytes),
     })
@@ -280,13 +284,13 @@ describe('NFT Upload ', () => {
       method: 'POST',
       headers: {
         Authorization: `Bearer ${client.token}`,
-        'Content-Type': 'application/car',
+        'Content-Type': 'application/vnd.ipld.car',
       },
       body: car,
     })
     const data2 = await res2.json()
     assert.equal(data2.value.cid, cid)
-    assert.equal(data2.value.type, 'application/car', 'car')
+    assert.equal(data2.value.type, 'application/vnd.ipld.car', 'car')
 
     const { data } = await rawClient
       .from('upload')
diff --git a/packages/client/src/lib.js b/packages/client/src/lib.js
index 14c03ed755..d1448c10c1 100644
--- a/packages/client/src/lib.js
+++ b/packages/client/src/lib.js
@@ -172,7 +172,7 @@ class NFTStorage {
         for await (const part of car) {
           carParts.push(part)
         }
-        const carFile = new Blob(carParts, { type: 'application/car' })
+        const carFile = new Blob(carParts, { type: 'application/vnd.ipld.car' })
         const cid = await pRetry(
           async () => {
             await rateLimiter()
diff --git a/packages/client/test/lib.spec.js b/packages/client/test/lib.spec.js
index b1a6dc4260..2075d399c7 100644
--- a/packages/client/test/lib.spec.js
+++ b/packages/client/test/lib.spec.js
@@ -104,7 +104,7 @@ describe('client', () => {
       for await (const part of out) {
         carParts.push(part)
       }
-      const car = new Blob(carParts, { type: 'application/car' })
+      const car = new Blob(carParts, { type: 'application/vnd.ipld.car' })
       const cid = await client.storeCar(car)
       assert.equal(cid, expectedCid)
     })
diff --git a/packages/client/test/service.js b/packages/client/test/service.js
index c5e4a59d05..0ec7da3665 100644
--- a/packages/client/test/service.js
+++ b/packages/client/test/service.js
@@ -20,7 +20,10 @@ const headers = ({ headers }) => ({
  */
 const importUpload = async (request) => {
   const contentType = request.headers.get('content-type') || ''
-  if (!contentType.includes('application/car')) {
+  const isCar =
+    contentType.includes('application/car') ||
+    contentType.includes('application/vnd.ipld.car')
+  if (!isCar) {
     throw new Error(`unexpected content type: ${contentType}`)
   }
   const content = await request.arrayBuffer()
diff --git a/packages/website/lib/mock_files.js b/packages/website/lib/mock_files.js
index df7f685e46..3b6640cc62 100644
--- a/packages/website/lib/mock_files.js
+++ b/packages/website/lib/mock_files.js
@@ -2,7 +2,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeic3a6txgjsavv57lvfud67y7zvz2eq2acp3wzbk5tey4xy72zvuyu',
     created: '2021-12-17T17:27:24.605+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     name: 'super special name for mocks',
     files: [],
@@ -18,7 +18,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreibe235afeycijr36lc5r3xjw7lrucbzilmx4eewv5666dlas2hxia',
     created: '2021-12-11T14:26:23.205+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     name: 'super special name 2 for mocks',
     files: [],
@@ -80,7 +80,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeiefibctpwu7tm25nxgcn3b5ywwskowkgccl4cbwnvtrgv6rsqjpxa',
     created: '2021-12-02T17:20:06.685+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     name: 'super special name 2 for mocks',
@@ -142,7 +142,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreidewg7t752npyue5wbhuwq53dfcxpms3yp7vfr7jn4l5noulyf2eu',
     created: '2021-11-11T19:53:37.954+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 215085,
@@ -233,7 +233,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreie3tjgq2phyctf2fippi5hbvhfu74qvagwn5yakq5xnmyv77azw7u',
     created: '2021-11-11T19:50:16.825+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 25342,
@@ -324,7 +324,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreifn43pu4gv45m46qopifih6khe3rxsnpgbnvpotb7julek7f2pcga',
     created: '2021-11-11T14:35:33.89+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 117704,
@@ -429,7 +429,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeid4fkhuzacw26xzd5zsm5w5zoh5ich7ujug6mfap2jseeucu6iqia',
     created: '2021-11-11T14:34:56.112+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 1096377,
@@ -534,7 +534,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeiagkmu65y4l6wvxolhgwrma3hplgl7aqm3rmyjgfpak6wuzclpgka',
     created: '2021-11-11T14:34:40.703+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 1095138,
@@ -639,7 +639,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeigp3wixuxy5jyssmvmpvxsde6tfnbvz73zlbd75n3vw5fbstahd6e',
     created: '2021-11-11T14:34:27.176+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 1094733,
@@ -744,7 +744,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeihxt2sua5pvhyfjoxwl6qkdk5s3yxo7flxtjemkuq7rhlnrobz63u',
     created: '2021-11-11T14:34:15.756+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 1089162,
@@ -849,7 +849,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeicdabe3cd366hjpwvtzgu7bdpz2tnc5gjulil53ynkowzn2h6hxai',
     created: '2021-11-11T14:34:03.956+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 1094558,
@@ -954,7 +954,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeidvorqswzkixzupzya4m37burj5oxswa3rf65nghybvfec2zubgya',
     created: '2021-11-11T14:33:49.415+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 1086294,
@@ -1059,7 +1059,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreibocn3taii22mjzxwcyczu2xxqlxjxpbymwc45nkeawixfmmjf5qi',
     created: '2021-11-11T14:33:11.606+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 179330,
@@ -1164,7 +1164,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreia4klzyfw4nqycdn3re7fggeimvnle3zylh5zba3aln3gtesje4u4',
     created: '2021-11-11T14:32:53.399+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 100721,
@@ -1419,7 +1419,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreiawfi33sq52ssimkml2htuhl2poq3sym5jk6mz23nh46hlb3mycbq',
     created: '2021-11-11T14:32:36.434+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 205142,
@@ -1524,7 +1524,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeihl3bkck7v56ta237bpkjymzcfc6gsge32nhh2f2tmttgegfn4x3q',
     created: '2021-11-11T14:32:16.619+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 776278,
@@ -1629,7 +1629,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeiemnso4riinbghkenyw2xvrui5frxbmkcyvlulflk54jpbubnbwaq',
     created: '2021-11-11T14:31:50.759+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 793259,
@@ -1734,7 +1734,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeidcikrfoerfbgbrkkf2etyjhaws6f2qf7hlvocwlrcygknq245uka',
     created: '2021-11-11T14:31:21.604+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 1015204,
@@ -1839,7 +1839,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeig3wxdo2xeipundiozlmqjmtp3epvktcwbo53h276ferzcwtuacbi',
     created: '2021-11-11T14:30:52.816+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 5160525,
@@ -1944,7 +1944,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeicsxx354iiuvpaypcdtpu2sct2wjonmh4y5kjipxls6ima7ju2g34',
     created: '2021-11-11T14:30:07.33+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 5751188,
@@ -2049,7 +2049,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeigmgqsmwy3wprkmsbpt3mwtcfsyleymhhlyzu7qieu2tezszvv6dy',
     created: '2021-11-11T14:29:40.718+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 2005672,
@@ -2259,7 +2259,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeifpsn6trnutbt434v2gph6zvlwicqssxrnrsbmu5n35ocg6u7s6ri',
     created: '2021-11-11T14:29:20.203+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 5622049,
@@ -2364,7 +2364,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreihggdz4hwbeh5vrffq42eo5w36my2dz6y6bl2sdjjakfsc4zml6hu',
     created: '2021-11-11T14:28:56.466+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 93475,
@@ -2574,7 +2574,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeif73pezyrz5ug5aacjnjxujctc2dyoem2g5injvr3y7mk45aatw4y',
     created: '2021-11-11T14:28:36.024+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 394675,
@@ -2949,7 +2949,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafkreiccjdgsev2zkqlvr6t64sicz3eaj2xibyehvyp2ty6h55qfruf5qu',
     created: '2021-11-11T14:28:19.996+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 61536,
@@ -3054,7 +3054,7 @@ export const MOCK_FILES = [
   {
     cid: 'bafybeibvlmcr7o6hwe2htf7nr3xypmv5f6sxi2jnjclk3xjero3fbxhdj4',
     created: '2021-11-11T14:28:03.331+00:00',
-    type: 'application/car',
+    type: 'application/vnd.ipld.car',
     scope: 'session',
     files: [],
     size: 2800699,
diff --git a/packages/website/pages/docs/how-to/mint-custom-metadata.md b/packages/website/pages/docs/how-to/mint-custom-metadata.md
index 57b64b2886..975ca0af51 100644
--- a/packages/website/pages/docs/how-to/mint-custom-metadata.md
+++ b/packages/website/pages/docs/how-to/mint-custom-metadata.md
@@ -131,7 +131,7 @@ The `------WebKitFormBoundary5peilISl2YOOweQy` tokens in the example above set t
 
 The `/upload` endpoint has some special support for IPFS Content Archives (CARs) that can be used to upload files larger than the 100 MiB single-request limit. 
 
-Uploading CAR files works just like uploading a single file. Send a `POST` request to `/upload`, with the `Content-Type` header set to `application/car` and the binary file data as the request body.
+Uploading CAR files works just like uploading a single file. Send a `POST` request to `/upload`, with the `Content-Type` header set to `application/vnd.ipld.car` and the binary file data as the request body.
 
 To upload files larger than 100 MiB, you can pack them into a CAR file and split the CAR into chunks, uploading each chunk in a separate HTTP request. See the [CAR file guide][guide-car-files] to learn more.
 
diff --git a/packages/website/public/schema.yml b/packages/website/public/schema.yml
index 5bf57b0c60..caa9e0ddbf 100644
--- a/packages/website/public/schema.yml
+++ b/packages/website/public/schema.yml
@@ -117,7 +117,10 @@ paths:
         ```
 
         ### Content Addressed Archive (CAR) files
-        You can also upload a CAR file, by setting the request body as a single CAR Blob/File object and providing the request header `Content-Type: application/car`
+        You can also upload a CAR file, by setting the request body as a single CAR Blob/File object and providing the request header `Content-Type: application/vnd.ipld.car`.
+        The Content-Type `application/car` is also supported for compatibility with an earlier version of this API, however the IANA media type
+        `application/vnd.ipld.car` should be preferred.
+
         Providing a CAR file allows you to pre-compute the root CID for 1 or more files, ensures that NFT.Storage will store and provide your assets with the same CID.
 
         ### Size limitations
@@ -156,6 +159,10 @@ paths:
             schema:
               type: string
               format: binary
+          application/vnd.ipld.car:
+            schema:
+              type: string
+              format: binary
           multipart/form-data:
             schema:
               type: object