API Mechanics

Authorization

Please contact SpaceKnow team to obtain an account.

Making Authorized Request

JWT (JSON Web Tokens) is used for authorization of every request against SpaceKnow APIs. JWT is sent in Authorization header after Bearer keyword (i.e. Authorization: Bearer JWT-TOKEN).

Example of an authorized request:

POST /credits/area/allocate-geojson
POST /credits/area/allocate-geojson HTTP/1.1
Host: spaceknow-imagery.appspot.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.t-IDcSemACt8x4iTMCda8Yhe3iZaWbvV5XKSTbuAn0M
{
    "companyId": 1
}

Get JWT

Use Auth0 Authentication API to get a JWT. Tokens are valid for 10 hours.

  • SpaceKnow client ID: hmWJcfhRouDOaJK2L8asREMlMrv3jFE1
  • SpaceKnow Auth0 domain: spaceknow.auth0.com

For example request for JWT in exchange for email and password looks like this:

POST https://spaceknow.auth0.com/oauth/ro

Example request:

POST /oauth/ro HTTP/1.1
Content-Type: application/json
{
    "client_id": "hmWJcfhRouDOaJK2L8asREMlMrv3jFE1",
    "username": "your_spaceknow_email@example.com",
    "password": "your_spaceknow_password",
    "connection": "Username-Password-Authentication",
    "grant_type": "password",
    "scope": "openid"
}
Response JSON Object:
 
  • id_token (string) – JWT to be later used in authorized API requests.

Example response:

HTTP/1.1 200 OK
Content-Type: application/json
{
    "id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.t-IDcSemACt8x4iTMCda8Yhe3iZaWbvV5XKSTbuAn0M",
    "access_token": "some-token",
    "token_type": "bearer"
}

To acquire a token in devel environment, fire the request above but change the following:

  • Spaceknow client ID: UWBUvt919N0sUXjG1CepGhiR0DJuazSY
  • SpaceKnow Auth0 domain: https://spaceknow-test.auth0.com

API Errors

The HTTP status code of 5XX is returned if a server-side error occurs. The status code of 4XX is returned if a client-side error occurs.

Error Response body:

{
    "error": "MACHINE-READABLE-ERROR-CODE",
    "errorMessage": "A human readable error description."
}

List of HTTP Status Codes

  • 400 - Bad Request. Make sure that the request body and headers are correct.
  • 401 - Unauthorized. You do not have sufficient rights or credits to perform this action.
  • 424 - Failed Dependency. This status code is returned when a failed processing pipeline is retrieved (see Asynchronous APIs).
  • 500 - Internal Server Error.
  • 503 - Service Unavailable. Try again later.

List of Error Codes

  • PAYLOAD-TOO-LARGE – request payload was too large. JSON in request body must be smaller than 64 KiB.
  • NON-EXISTENT-ENDPOINT - requested path does not correspond to any API endpoint.
  • EXTENT-TOO-LARGE - the requested extent was too large to be processed by the API. Try again with a smaller extent.
  • EXTENT-TOO-SMALL – requested extent is too small.
  • NO-VALID-PIXELS - requested scene has no valid pixels inside requested extent.
  • NON-EXISTING-SCENE - scene with given ID was not found when processing your request.
  • RESOLUTION-TOO-COARSE - image resolution is too coarse. An image with finer GSD is needed to be properly processed by the algorithm.
  • ACCESS-DENIED - requesting client is not permitted to do perform an operation or access the resource.
  • API-KEY-AUTHORIZATION-NOT-PERMITTED - other than user authentications are not available for the endpoint. See Authorization.
  • IMAGE-HAS-INVALID-PIXELS-ABOVE-TOLERANCE - This error may occur when analysis is requested on an incomplete image. For example this may happen close to scene boundaries.
  • INVALID-CURSOR - provided paging cursor is invalid.
  • ORDER-SCENE-NOT-SUPPORTED – this scene cannot be ordered.
  • ORDER-TOOK-TOO-LONG – this error occurs if a scene’s order takes too long on provider’s side.
  • EXTENT-HAS-NO-INTERSECTION – extent doesn’t intersect scene.
  • PROVIDER-ERROR – a request to imagery provider resulted in an unrecoverable error.
  • IMAGERY-FETCH-TIMEOUT – fetching imagery from provider’s system took too long.
  • TOO-BIG-TILE-AREA - requested web map tile(s) covers too broad area.
  • TILE-OUTSIDE-SCENE - requested web map tile is outside specified scene.
  • ZERO-TILES-AVAILABLE - none of requested web map tile(s) succeeded. See Kraken API (Imagery and Analyses).
  • ZOOM-LEVEL-GREATER-THAN-MAX-ZOOM - requested tile with too high zoom.
  • SCENES-HAVE-NO-INTERSECTION - footprints of provided scenes don’t intersect.
  • NINJA-ENTITY-DOES-NOT-EXIST - the affected entity in Ninja API doesn’t exist.
  • NINJA-GROUP-DOES-NOT-EXIST - the affected entity group in Ninja API doesn’t exist.
  • NOT-NINJA-GROUP-READER - you need reader permission to access the group to perform the action.
  • NOT-NINJA-GROUP-EDITOR - you need editor permission to access the group to perform the action.
  • ENTITY-ALREADY-IN-GROUP - you tried to add an entity to the group but the entity already exists in the group.
  • NOT-NINJA-ADMIN - you have to be an admin to perform the operation (e.g. to change another user’s data).
  • NON-EQUAL-SIZE-MASKS - an operation requires masks of equal shape
  • INVALID-GEOJSON - requested GeoJSON doesn’t fit requirements of the API.
  • NO-VALID-BINDING - affected user is not bound to any company. See Credits API (Billing, Payments and Credits).
  • NOT-ENOUGH-CREDITS - user’s group does not have enough credits to perform requested operation.
  • NON-EXISTENT-GROUP - accessed group does not exist. See Credits API (Billing, Payments and Credits).
  • NON-EXISTENT-USER - accessed user does not exist.
  • PROCESSOR-DECLINED - customer’s bank has refused the transaction request.
  • GATEWAY-REJECTED - transaction did not pass gateway rules.
  • INVALID-NONCE - transaction did not pass gateway rules.
  • PAYMENT-ERROR - unspecified payment error.
  • INVALID-FILE-ID - requested File ID is not valid.
  • NON-EXISTENT-GEOMETRY - GeoJSON geometry does not exist.
  • NON-EXISTENT-FEATURE - GeoJSON feature does not exist.

Asynchronous APIs

Processes, that can take from minutes to hours, are handled asynchronously in the “pipeline”. All APIs that work asynchronously have ../initiate and ../retrieve endpoints. To trigger a new pipeline, use ../initiate. To check whether a pipeline is finished, request /check-status endpoint of Tasking API. To get a finished pipeline result, request ../retrieve.

POST /.../initiate
Response JSON Object:
 
  • pipelineId (string) – ID of the processing pipeline. It will be used later to check pipeline status and to retrieve pipeline result.
  • status (string) – status of the pipeline at the time the response was generated. See Tasking API to learn more about pipeline statuses.

Example response:

{
    "pipelineId": "3g4PovfhGxmymQolpgvv",
    "status": "NEW"
}

Pipeline is stopped and set to the FAILED status if an error occured during pipeline processing. Request on ../retrieve for the failed pipeline is responded with a status code 424, and with a specific error code and message. See API Errors.

POST /.../retrieve
Request JSON Object:
 
  • pipelineId (string) – required; ID of the pipeline whose result should be retrieved.

Example request:

{
    "pipelineId": "3g4PovfhGxmymQolpgvv"
}

Extent

Extent is a GeoJSON whose minimum bounding rectangle (MBR) is non-empty. All coordinates are considered to be expressed in WGS84 coordinate reference system.

Example extent:

{
    "type": "GeometryCollection",
    "geometries": [
        {
            "type": "Polygon",
            "coordinates": [
                [
                    [
                        14.452436864376,
                        50.092111002982
                    ],
                    [
                        14.451779723167,
                        50.092107561411
                    ],
                    [
                        14.452233016491,
                        50.091543140472
                    ],
                    [
                        14.452436864376,
                        50.092111002982
                    ]
                ]
            ]
        }
    ]
}

Extent Decomposition

Extent can be too large to be used with a particular API / system. We recommend to use Kraken API (Imagery and Analyses) in such cases.

This problem can be also solved on client side by decomposing the extent into a grid of smaller tiles (squares).

A simple decomposition determines the smallest bounding rectangle of the extent, whose side lengths are multiples of a desired tile size.

The bounding rectangle is then “cut” into square tiles. Tiles that do not intersect requested area could be omitted if desired.

Single tile has these properties:

  • square
  • intersection of the square with original polygon

The decomposition described above is “naive” as it uses a planar solution to the problem. It is recommended to use a CRS, which is a planar approximation of the earth in the area of the original extent.

API Response Headers

Following headers might be contained in API response:

  • SpaceKnow-Api-Version
  • SpaceKnow-Request-Id - unique identifier of the request. You may use it when contacting SpaceKnow engineering team about any technical issues.

Example response header:

HTTP/2 200
server: nginx
date: Wed, 03 Jan 2018 15:47:16 GMT
content-type: application/json; charset=utf-8
content-length: 55
vary: Accept-Encoding
cache-control: no-cache
access-control-allow-origin: *
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
strict-transport-security: max-age=2592000; includeSubDomains
via: 1.1 google
alt-svc: hq=":443"; ma=2592000; quic=51303431; quic=51303339; quic=51303338; quic=51303337; quic=51303335,quic=":443"; ma=2592000; v="41,39,38,37,35"
spaceknow-api-version: 106
spaceknow-request-id: QyhRiSw87c

Paging

Some APIs may return a big number of results. To avoid large JSON responses, the results are paginated using cursor as a pointer to a specific page.

Put parameter cursor to request an object to obtain a specific page.

Example of a specific page request:

{
    "search": "*",
    "cursor": "Pu9ZyvlVXxkm0XNr2FLr"
}

If the cursor is omitted, then the first page is returned.

Example of the first page request:

{
    "search": "*"
}

Paginated APIs return cursor which is a pointer to the next page and results which is a list of entities of the returned page.

Example of the paginated response:

{
    "results": [
        {
            "name": "Enterprise 1"
        },
        {
            "name": "Enterprise 2"
        },
        {
            "name": "Enterprise 3"
        },
        {
            "name": "Enterprise 4"
        },
        {
            "name": "Enterprise 5"
        }
    ],
    "cursor": "Pu9ZyvlVXxkm0XNr2FLr"
}

cursor is null if the last page was returned.

Example of the last page response:

{
    "results": [
        {
            "name": "Enterprise 6"
        }
    ],
    "cursor": null
}

Both normal and asynchronous APIs may be paginated. In the case of asynchronous APIs a new pipeline is started for every new requested page.