Developer tools
File uploads

File upload guide

Use the File Upload API to securely send dispute evidence, identification documents, and more to Stripe.

When you upload a file to Stripe using the API, a file token and other information about the file is returned. The token can then be used in other API calls. This guide provides a detailed walk-through of this process.

Uploading a file

To upload a file, send a multipart/form-data request to https://files.stripe.com/v1/files. Note that the subdomain files.stripe.com is different than most of Stripe’s API endpoints. The request should specify a purpose and a file. The following example uploads a file located at /path/to/a/file.jpg on your local file system with the purpose dispute_evidence:

curl https://files.stripe.com/v1/files \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -F file="@/path/to/a/file.jpg" \ -F purpose=dispute_evidence
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' Stripe::File.create({ file: File.new('/path/to/a/file.jpg'), purpose: 'dispute_evidence', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' with open('/path/to/a/file.jpg', 'rb') as fp: stripe.File.create( file=fp, purpose='dispute_evidence', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $fp = fopen('/path/to/a/file.jpg', 'r'); \Stripe\File::create([ 'file' => $fp, 'purpose' => 'dispute_evidence', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; FileCreateParams params = FileCreateParams.builder() .setFile(new java.io.File("/path/to/a/file.jpg")) .setPurpose(FileCreateParams.Purpose.DISPUTE_EVIDENCE) .build(); File upload = File.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const fp = fs.readFileSync('/path/to/a/file.jpg'); const upload = await stripe.files.create({ file: { data: fp, name: 'file.jpg', type: 'application.octet-stream', }, purpose: 'dispute_evidence', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" fp, _ := os.Open("/path/to/a/file.jpg") params := &stripe.FileParams{ FileReader: fp, Purpose: stripe.String(string(stripe.FilePurposeDisputeEvidence)), Filename: stripe.String("file.jpg"), } upload, _ := file.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var filename = "/path/to/a/file.jpg"; using (FileStream stream = System.IO.File.Open(filename, FileMode.Open)) { var service = new FileService(); var options = new FileCreateOptions { File = stream, Purpose = FilePurpose.DisputeEvidence, }; Stripe.File upload = service.Create(options); }

The following example uploads a file using our Android SDK with the purpose dispute_evidence:

class CheckoutActivity : AppCompatActivity() { private val stripe: Stripe by lazy { Stripe(this, "pk_test_TYooMQauvdEDq54NiTphI7jx") } private fun uploadFile(file: File) { stripe.createFile( StripeFileParams( file, StripeFilePurpose.DisputeEvidence ), callback = object : ApiResultCallback<StripeFile> { override fun onSuccess(result: StripeFile) { // File upload succeeded } override fun onError(e: Exception) { // File upload failed } } ) } }
public class CheckoutActivity extends Activity { private Stripe stripe; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); stripe = new Stripe( this, "pk_test_TYooMQauvdEDq54NiTphI7jx" ); } private void uploadFile(@NotNull File file) { stripe.createFile( new StripeFileParams( file, StripeFilePurpose.DisputeEvidence ), new ApiResultCallback<StripeFile>() { @Override public void onSuccess(@NonNull StripeFile result) { // File upload succeeded } @Override public void onError(@NonNull Exception e) { // File upload failed } } ); } }

There are several valid purpose values, each with file format and size requirements.

Purpose Description Supported Mimetypes Max Size Expiry Downloadable
business_icon A business icon. JPEG
PNG
GIF
512KB NEVER true
business_logo A business logo. JPEG
PNG
GIF
512KB NEVER true
customer_signature Customer signature image JPEG
PNG
4MB NEVER true
dispute_evidence Evidence to submit with a dispute response. PDF
JPEG
PNG
8MB 9 months true
identity_document A document to verify the identity of an account owner during account provisioning. PDF
JPEG
PNG
16MB NEVER false
pci_document A self-assessment PCI questionnaire. PDF
16MB NEVER true
tax_document_user_upload A user-uploaded tax document. PDF
CSV
JPEG
PNG
XLSX
DOCX
16MB NEVER true
additional_verification Additional verification for custom accounts PDF
JPEG
PNG
16MB NEVER false

The MIME type of the file you wish to upload must correspond to its file format.

File Format MIME Type
CSV text/csv
DOCX application/vnd.openxmlformats-officedocument.wordprocessingml.document
GIF image/gif
HTML text/html
JPEG image/jpeg
JSON application/json
PDF application/pdf
PNG image/png
TIFF image/tiff
TSV text/tab-separated-values
TXT text/plain
XLSX application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
XML application/xml
ZIP application/zip

A successful request returns a file_upload object.

Retrieving a File API resource

To retrieve the API resource for a File, make a GET request to the /v1/files endpoint of the files.stripe.com subdomain providing the file upload ID:

curl https://files.stripe.com/v1/files/file_Yd4TfsCmBIettwHv65VK \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc:
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' upload = Stripe::File.retrieve('file_Yd4TfsCmBIettwHv65VK')
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' upload = stripe.File.retrieve('file_Yd4TfsCmBIettwHv65VK')
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $upload = \Stripe\File::retrieve('file_Yd4TfsCmBIettwHv65VK');
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; File upload = File.retrieve("file_Yd4TfsCmBIettwHv65VK");
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const upload = await stripe.files.retrieve('file_Yd4TfsCmBIettwHv65VK');
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" upload, _ := file.Get("file_Yd4TfsCmBIettwHv65VK", nil)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var service = new FileService(); var upload = service.Get("file_Yd4TfsCmBIettwHv65VK");

Downloading File Contents

If the file purpose allows downloading the file contents, then the file_upload includes a non-null url field indicating how to access the contents. This url requires authentication with your Stripe API keys.

curl https://files.stripe.com/v1/files/file_Yd4TfsCmBIettwHv65VK/contents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ --output "my_file.png"

If you want unauthenticated access to a file whose purpose allows downloading, then you can produce anonymous download links by creating a file_link.

curl https://api.stripe.com/v1/file_links \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d file=file_Yd4TfsCmBIettwHv65VK
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' Stripe::FileLink.create({ file: 'file_Yd4TfsCmBIettwHv65VK', })
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' stripe.FileLink.create( file='file_Yd4TfsCmBIettwHv65VK', )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); \Stripe\FileLink::create([ 'file' => 'file_Yd4TfsCmBIettwHv65VK', ]);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; FileLinkCreateParams params = FileLinkCreateParams.builder() .setFile("file_Yd4TfsCmBIettwHv65VK") .build(); FileLink fileLink = FileLink.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const fileLink = await stripe.fileLinks.create({ file: 'file_Yd4TfsCmBIettwHv65VK', });
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.FileLinkParams{ File: stripe.String("file_Yd4TfsCmBIettwHv65VK"), } link, _ := filelink.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new FileLinkCreateOptions { File = "file_Yd4TfsCmBIettwHv65VK", }; var service = new FileLinkService(); var fileLink = service.Create(options);

The file_link resource has a url field that will allow unauthenticated access to the contents of the file.

Using a file

After a file is uploaded, the file upload ID can be used in other API requests. For example, to attach an uploaded file to a particular dispute as evidence:

curl https://api.stripe.com/v1/disputes/dp_ZNEv2XfUWocKAJFe2qJB \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "evidence[receipt]"=file_Yd4TfsCmBIettwHv65VK
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' Stripe::Dispute.update( 'dp_ZNEv2XfUWocKAJFe2qJB', { evidence: { receipt: 'file_Yd4TfsCmBIettwHv65VK', }, } )
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' stripe.Dispute.modify( 'dp_ZNEv2XfUWocKAJFe2qJB', evidence={ 'receipt': 'file_Yd4TfsCmBIettwHv65VK', }, )
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); \Stripe\Dispute::update( 'dp_ZNEv2XfUWocKAJFe2qJB', [ 'evidence' => [ 'receipt' => 'file_Yd4TfsCmBIettwHv65VK', ], ] );
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; Dispute dispute = Dispute.retrieve("dp_ZNEv2XfUWocKAJFe2qJB"); DisputeUpdateParams params = DisputeUpdateParams.builder() .setEvidence( DisputeUpdateParams.Evidence.builder() .setReceipt("file_Yd4TfsCmBIettwHv65VK") .build()) .build(); dispute.update(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const dispute = await stripe.disputes.update( 'dp_ZNEv2XfUWocKAJFe2qJB', { evidence: { receipt: 'file_Yd4TfsCmBIettwHv65VK', }, } );
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.DisputeParams{ Evidence: &stripe.DisputeEvidenceParams{ Receipt: stripe.String("file_Yd4TfsCmBIettwHv65VK"), }, } dis, _ := dispute.Update("dp_ZNEv2XfUWocKAJFe2qJB", params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new DisputeUpdateOptions { Evidence = new DisputeEvidenceOptions { Receipt = "file_Yd4TfsCmBIettwHv65VK", }, }; var service = new DisputeService(); var dispute = service.Update("dp_ZNEv2XfUWocKAJFe2qJB", options);

Note that you can only use an uploaded file in a single API request.

Handling Upload Errors

When you use the File API to upload a PDF document, we run it through a series of checks to validate that it is correctly formatted and meets PDF specifications. We return an error for uploads that fail any of our checks.

Try the following to fix errors that we detect:

  • Remove annotations or additional media you added to the document.
  • If you cannot remove your annotations or media, or if you combined several PDFs into one, try using your computer’s Print to PDF function to create a fresh document.
Was this page helpful?
Questions? Contact us.
Developer tutorials on YouTube.