Contentful logo

Contentful Community

API Upload images

I’m trying to upload images through the Upload API. Having an issue where the linked image resource within the newly created ASSET is broken.

Going to the asset it states that the image “is loading”, however this never changes.

I’ve followed the documentation and also the information laid out in this contentful blog post, however no dice.

I’ve also checked the data content [base64] of the API call on a 3rd party base64 decoding website and the image displays as expected.

All the API calls state a successful response also. Any ideas?

Inside each asset it states that the file/image is loading, however this doesn’t change.

This is the data that’s being set for the new Asset to assign the file against it. Data is a passed object where data.id is the response.sys.id of the upload response of the file. Response to this is success.

"data" : JSON.stringify({
	"fields": {
		"title": {
			"en-US": data.title
		},
		"file": {
			"en-US": {
				"contentType": data.type,
				"fileName"	 : data.filename,
				"uploadFrom" : {
				  	"sys" : {
				    	"type"		: "Link",
				    	"linkType"	: "Upload",
				    	"id" 		: data.id
				  	}
				}
			}
		}
	}
})

The direct file upload is for uploading binary assets, not base64 encoded images. Upload the image itself, not a base64 encoding of the image.

As the referenced blog post shows, you should be sending an octet-stream:

$ curl -i -XPOST \
  -H "Content-Type:application/octet-stream" \
  -H "Authorization: Bearer <accessToken>" \
  --data-binary "@/Users/ben/my-cute-cat.jpg" \
  https://upload.contentful.com/spaces/<spaceId>/uploads

Is there a specific reason you are trying to use a base64 encoded image?

I tried this, however each time it came back with an error when trying to add the asset after a successful response for uploading the image.

BadRequest : Invalid JSON in request body: ����\u0000\u0010JFIF\u0000\u0001....

However when using base64 the error does not exist. And hence, I was creating the asset, now it doesn’t. It worked also when adding a remote image to the asset. It’s only when binary is used it fails. Hence why I was using base64.

You can’t put a binary file into the create asset request directly. You need to upload the file to upload.contentful.com as shown the in code snippet above then take the response which has an upload ID and use it when making the create asset request. The main steps are:

  1. Upload image
  2. Create asset
  3. Process asset
  4. Publish asset

Check the blog post again and make sure you are not leaving out any steps: https://www.contentful.com/blog/2017/03/02/uploading-files-directly-to-contentful/

What programming language are you using? We can give you an example in that language if needed.

Yes, I’m aware of that. If you look at the JSON in my above post you can see that I’m trying to pass a newly created resource into a new asset.

Are you processing the asset after you create it? The web app does that automatically but if you create an asset via the API you have to process it via the API as well

I’m only processing the newly created ASSET as stated by the documentation. Am I meant to be processing the new resource too, prior to creating the ASSET?

You need to process the asset after creating it and before publishing it.

Just to be clear you don’t need to and can’t in fact process the upload (aka resource)

That is exactly what I am doing! It was your response that you edited that mentioned the processing of the resource. Which is why I mentioned that I’m following the documentation as it does not state processing of the resource.

Can you share the code you are using for the whole process?

Do you have access to my account to see what is going on with the creation of resources/files on the server? Because as a developer how am I meant to know if the resource was even created correctly?

Please go to https://www.contentful.com/support/ to submit a support ticket where we can look at your account and help with this in a more detailed manner.

For this public forum it would be helpful if you could share the code you are using so we can help you fix the problem. If you don’t want to share publicly that’s completely fine but our support team will also ask to see your code.

Finally resolved the issue. I can confirm that the API works as expected.

I will say following those steps, it’s not very clear about how one publishes an asset after processing it, if you’re not using the supplied SDK. It’s clearly not as simple as the 1, 2, 3, 4, as stated.

Does one have to continually poll the server to see if the asset has been processed? What determines that the asset has been processed, as looking at the JSON response of getting an asset there nothing in that to determine it.

Hi Scott,

Normally asset processing happens very quickly, but it is asynchronous so it doesn’t happen immediately. What the SDKs and other tooling we’ve developed does behind the scenes is to poll the API for the asset until the response has a fields.file[locale].url key and value. That is the best indicator that the file has completed processing.

Many thanks Charlie. I’ll try that.

Actually, I was having trouble uploading through the website yesterday. Could it also have been a connectivity issue?