Grandad, is that you?

Your browser is out of date and doesn't support all of the cool stuff we do on our website.

We like Google Chrome, but any modern browser will do.Update my browser now


Add / Update Funding Project

Add or update a project.

The project to be updated should be stored as a JSON-serialised document in the request data. We will attempt to update any project with the same project_id: if none is found we assume it's a new project.

You can use the get project by UUID call to check the posted project.

Resource URL




HTTP 200: OK

Returns with a status code of 200 and the UUID of the project in a JSON dictionary e.g:

{"uuid": "b4df7b093b9b33fbbc11be54bf8355cb"}


HTTP 401: bad request

Indicates that the project document is malformed. The response content will contain a JSON document with a key "detail" which will itself contain a dictionary describing each field error. For example:

{ "detail" : { "funding_type": u"Invalid funding type code XX: please select one from ME, MD, C, MF, E, D, RS, ML, DE, L, O, IV, R, IN, Y" } }

HTTP 403: permisson denied

Indicates that an attempt was made to add or update a project for a platform that you don't have permission to update. Check that you are using the correct platform_id.


The following example inserts a single rewards funding project for platform Kickstarter.

Add / Update Funding Project


Using the standard curl command:

curl -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Token abcdef123456890" \ -d '{ "currency": "GBP", "description": "This widget will change your life!", "funding_type": "R", "goal": 10000, "language": "en", "platform_id": 443, "project_id": "12345", "raised": 500, "title": "A new widget" }' \

We depend on the very useful requests library.

import requests import json payload = { "currency": "GBP", "description": "This widget will change your life!", "funding_type": "R", "goal": 10000, "language": "en", "platform_id": 443, "project_id": "12345", "raised": 500, "title": "A new widget" } r ='', headers={'Authorization': 'Token abcdef123456890', 'Content-Type': 'application/json'}, data = json.dumps(payload)) if r.status_code == 200: # We return the UUID field for successfully uploaded projects: print("UUID: %s" % r.json()['uuid']) else: print("Failed: errors = %r" % r.json()['detail'])

Assumes that Guzzle has been installed using Composer.

require 'vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; $client = new GuzzleHttp\Client(); try { $response = $client->post('', [ "headers" => [ "Accept" => "application/json", "Content-Type" => "application/json", "Authorization" => "Token abcdef123456890" ], "json" => [ "language" => "en", "description" => "This widget will change your life!", "funding_type" => "R", "currency" => "GBP", "goal" => 10000, "platform_id" => 443, "project_id" => "12345", "title" => "A new widget", "raised" => 500 ] ]); $json = $response->json(); /* We return the UUID field for successfully uploaded projects: */ $uuid = $json["uuid"]; var_dump($uuid); } catch (ClientException $e) { /* Failed uploads should return a "detail" dictionary describing the invalid fields: */ $errors = $json["detail"]; var_dump($errors); }

We use the Fluent API component of the Apache HttpComponents library.

Here's the Maven POM file:

4.0.0 crowdsurfer_post cspost 1.0-SNAPSHOT org.apache.httpcomponents httpclient 4.5 org.apache.httpcomponents fluent-hc 4.5

And here's the Java class. Note that unlike the other examples we assume that the project has already seen serialised as a JSON string. Obviously in production you would be mapping from your database entities into JSON (possibly using json-simple or equivalent).

package com.crowdsurfer.projects; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpResponseException; import org.apache.http.client.fluent.Request; import org.apache.http.entity.ContentType; import org.apache.http.util.EntityUtils; import; import java.nio.file.Files; import java.nio.file.Paths; public class APIPoster { private String token; public final static String URL = ""; public APIPoster(String apitoken) { token = apitoken; } public String postFromFile(String filename) throws IOException { String json = new String(Files.readAllBytes(Paths.get(filename))); return postJson(json); } public String postJson(String projectjson) throws IOException { HttpResponse response = Request.Post(URL) .addHeader("Authorization", "Token "+token) .bodyString(projectjson, ContentType.APPLICATION_JSON) .execute().returnResponse(); StatusLine status = response.getStatusLine(); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity); if (status.getStatusCode() == 200) { return responseString; } if (status.getStatusCode() == 400) { // Invalid request: check that your formatting matches the schema we are expecting. // (A usual suspect is date string formatting: we're expecting UTC format of YYYY-MM-DD) throw new HttpResponseException(status.getStatusCode(), responseString); } else { // something else went wrong (probably a bug on our side) throw new HttpResponseException(status.getStatusCode(), status.getReasonPhrase()); } } public static void main(String[] args) { APIPoster poster = new APIPoster(args[0]); try { String response = poster.postFromFile(args[1]); System.out.println("POST succeeded: "+response); } catch (IOException e) { System.err.println("Failed to post file: "+e); } } }