.. Copyright (C) 2016-2024 SpaceKnow, Inc. ============= API Mechanics ============= .. _api.mechanics.authorization: ************* Authorization ************* .. only:: not holygrail Please contact `SpaceKnow`_ team to obtain an account. .. _SpaceKnow: https://spaceknow.com/support/ 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``). .. _JWT (JSON Web Tokens): https://jwt.io/ **Example of an authorized request**: .. http:post:: /imagery/search/initiate .. only:: not holygrail .. sourcecode:: http POST /imagery/search/initiate HTTP/1.1 Host: api.spaceknow.com Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.t-IDcSemACt8x4iTMCda8Yhe3iZaWbvV5XKSTbuAn0M .. only:: holygrail .. sourcecode:: http POST /imagery/search/initiate HTTP/1.1 Host: api.local Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.t-IDcSemACt8x4iTMCda8Yhe3iZaWbvV5XKSTbuAn0M .. sourcecode:: json { "provider": "gbdx", "dataset": "idaho-pansharpened", "extent": { "type": "Polygon", "coordinates": [[ [115.84512233734131, -31.96024562403475], [115.84490776062012, -31.96559774488045], [115.84851264953612, -31.965452113067933], [115.84842681884766, -31.96053690394404], [115.84512233734131, -31.96024562403475] ]] } } Get JWT ======= .. only:: not holygrail Obtaining JWT tokens by clients is currently only supported for Auth0 OIDC provider. Use `Auth0 Authentication API`_ to get a JWT. Tokens are valid for 10 hours. .. _Auth0 Authentication API: https://auth0.com/docs/api/info#authentication-api * SpaceKnow client ID: ``hmWJcfhRouDOaJK2L8asREMlMrv3jFE1`` * SpaceKnow Auth0 domain: ``spaceknow.auth0.com`` For example request for JWT in exchange for `email and password`_ looks like this: .. _email and password: https://auth0.com/docs/api/authentication?http#database-ad-ldap-active- .. http:post:: https://spaceknow.auth0.com/oauth/ro **Example request**: .. sourcecode:: http POST /oauth/ro HTTP/1.1 Content-Type: application/json .. sourcecode:: json { "client_id": "hmWJcfhRouDOaJK2L8asREMlMrv3jFE1", "username": "your_spaceknow_email@example.com", "password": "your_spaceknow_password", "connection": "Username-Password-Authentication", "grant_type": "password", "scope": "openid" } :>json string id_token: JWT to be later used in authorized API requests. **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json .. sourcecode:: 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`` .. only:: holygrail Use `FusionAuth Authentication API`_ to get a JWT. Tokens are valid for 10 hours. .. _FusionAuth Authentication API: https://fusionauth.io/docs/v1/tech/oauth/#example-resource-owner-password-credentials-grant For example request for JWT in exchange for email and password looks like this: .. http:post:: http://fusionauth.local/oauth2/token **Example request**: .. sourcecode:: http POST /oauth2/token HTTP/1.1 Content-Type: application/x-www-form-urlencoded :formparam grant_type: always set to ``password`` for Resource Owner Password Credentials Grant :formparam username: your_holygrail_email@example.com :formparam password: your_holygrail_password :formparam scopes: always set to ``openid`` :formparam client_id: always set to ``8ed4ebd4-cd8b-4c46-ab81-8e8d7fda42a4`` :>json string access_token: JWT to be later used in authorized API requests. **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json .. sourcecode:: json { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkY2Vm9Kd1BaN1Jyc1BpVVJzdGVSVWFFeVZkOCJ9.eyJhdWQiOiI4ZWQ0ZWJkNC1jZDhiLTRjNDYtYWI4MS04ZThkN2ZkYTQyYTQiLCJleHAiOjE2MDA0NDIzMDcsImlhdCI6MTYwMDQzODcwNywiaXNzIjoiaG9seWdyYWlsLmxvY2FsIiwic3ViIjoiMDdjOGNhYTctMWJiZC00OTU2LWE3MWMtOWI1MjE3NmU5YjBlIiwianRpIjoiYmZhZjMzZDktNjAxOC00YmRjLThjMTctZTU4NzU1NjVhMWQ4IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6Imk5bi10ZXN0c0BzcGFjZWtub3cuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWV9.fgvHbYYxccCgjyUGOThQ7hXcEXO39z0amLKLJ-92miFU73WxfDpfcxAdBEcbMsvFM8MswGjqRA5yb4GAIgkY9rJ2VVdjWZ07i9qSeswakqcwRoZsH5WpB7IZ69HjXMSaGd7IXhPj_xWszcDAxr1Cdk4uPQOLLhSr7J-sTroQmn6F8u20_WoShIfNwomTeoOjVynCFX3H7dBdK3_U2ODHbUtu7Tnf4HDAklgLJu_XFSrfqR3MGbfuY2emcfhVuXDcIQ3b8SZ8DzpU2_KirbBpfhHsJm6Xj09l7pGbPbA1PK2FvdaYUWOBa4XLrdJGuS5yh3oPm9cMIkaLCw6l4gpas1trqgu8A-hqiUpvMCSCKH5tCDJDZLOSzG_Y0Fj_Ugs2T5zN30cah0Rx-uw7SEOJeObVdgjHI-9ve0HOcKhQQI5eVkv_XjdbdLEYd0I8LJUiuFayw1KhnVCm3V5VsC32ZlrqLQwMYp_jPwRquiCBzjjN6TuyQZ5h8i4fVnV3y8_F3EQdAJeRNby5fac4qddRlpaxOzL4OkibSCscCq-rL0H5vl62DWtHrdD1_JdvhycUJwaBqNBrRlojhtSvjCtxQTNx_gwJCvwcVrsupjdT4hh_avGJhWVtTAoUUt3cuZ1fTjngOmHx_WurkPr_Ru2EueiaoQ-VRu6DM18ZDDXj5BY", "expires_in": 3599, "token_type": "Bearer", "userId": "07c8caa7-1bbd-4956-a71c-9b52176e9b0e" } .. _api.mechanics.permissions: *********** Permissions *********** Most SpaceKnow API endpoints have a set of permissions required to access them. A permission is a string with ``.`` as a namespace separator, for example ``imagery.availability``. The following Python code snipped shows how permissions are tested. .. code-block:: python user_permission = user_permission_str.split('.') required_permission = required_permission_str.split('.') test_len = min(len(user_permission), len(required_permission)) user_permission_part = user_permission[:test_len] required_permission_part = required_permission[:test_len] return user_permission_part == required_permission_part See the following example, where columns are permissions of a user and rows required permission. +--------------------------------------------------+--------------------------+-------------------------------+------------+-------------+ | | ``imagery.availability`` | ``imagery.availability.gbdx`` | ``kraken`` | ``imagery`` | +--------------------------------------------------+--------------------------+-------------------------------+------------+-------------+ | ``imagery.availability`` | true | true | false | true | +--------------------------------------------------+--------------------------+-------------------------------+------------+-------------+ | ``imagery.availability.gbdx.idaho-pansharpened`` | true | true | false | true | +--------------------------------------------------+--------------------------+-------------------------------+------------+-------------+ | ``imagery.availability.pl`` | true | false | false | true | +--------------------------------------------------+--------------------------+-------------------------------+------------+-------------+ | ``imagery.images`` | false | false | false | true | +--------------------------------------------------+--------------------------+-------------------------------+------------+-------------+ | ``imagery`` | true | true | false | true | +--------------------------------------------------+--------------------------+-------------------------------+------------+-------------+ .. only:: not holygrail See also :ref:`api.user`. .. _api.mechanics.errors: ********** 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**: .. code-block:: json { "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. * 403 - Forbidden. You are trying to modify internal assets. * 424 - Failed Dependency. This status code is returned when a failed processing pipeline is retrieved (see :ref:`Asynchronous API `). * 500 - Internal Server Error. * 503 - Service Unavailable. Try again later. List of Error Codes =================== General API Error Codes ----------------------- * ``NOT-AUTHORIZED`` -- the request is either not properly :ref:`authorized ` or you do not have sufficient :ref:`permissions`. * ``PAYLOAD-TOO-LARGE`` -- request payload was too large. Request payload of majority API endpoints must be at most 64 KiB large. * ``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. * ``NON-EXISTENT-GEOMETRY`` -- GeoJSON geometry does not exist. * ``UNSUPPORTED-IMAGERY`` -- provided imagery is not supported by the algorithm. * ``GSD-TOO-COARSE`` -- scene GSD (ground sample distance) is bigger than the maximum supported for given map type. * ``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 :ref:`api.mechanics.authorization`. * ``AUTHORIZATION-WITHOUT-CONTEXT-NOT-PERMITTED`` -- endpoint requires proper user authentication or request context containing user_id and accounting for API key. * ``INTERFEROGRAM-BASELINE-TOO-SMALL`` -- This error may occur in SLC data analysis when analyzed tile is too close to the edge of scene and algorithm is not able to extract useful results. * ``INVALID-CURSOR`` -- provided paging cursor is invalid. * ``METHOD-NOT-ALLOWED`` -- chosen HTTP method is not supported by this endpoint, refer to the documentation or use HTTP OPTIONS to find the supported methods * ``INVALID-JWT`` -- provided authorization token is not valid * ``INVALID-QUERY-PARAMETER`` -- provided query parameter is not valid. * ``FORBIDDEN`` -- requested change of internal assets. * ``UNSUPPORTED-ENVIRONMENT`` -- endpoint is not supported for the environment (e.g. some on-prem deployment) .. Use - instead of * for bullet list. * in ``only`` results in bold text. .. only:: not holygrail - ``CREDITS-ERROR`` -- imagery or analysis was requested for an area or time range that was not yet fully allocated. See :ref:`api.credits` for more information. Tasking API Error Codes ----------------------- * ``NON-EXISTENT-PIPELINE`` -- pipeline with given ID was not found when processing your request. * ``PIPELINE-NOT-PROCESSED`` -- pipeline has not been resolved yet. Ragnar API Error Codes ---------------------- * ``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. * ``PROVIDER-RESTRICTION`` -- imagery provider refused to serve given scene for given account. This may be to licensing or geo-spatial restrictions. * ``PROVIDER-UNAVAILABILITY`` -- imagery provider indicated that required data are not readily available in their systems. * ``SEARCH-TOO-COARSE`` -- search parameters are too coarse please narrow down the search parameters. * ``OUTDATED-METADATA`` -- requested scene has outdated metadata and cannot be used. * ``OUTDATED-METADATA-SEARCH-AGAIN`` -- requested scene has outdated metadata. Run search again. * ``IMAGERY-FETCH-TIMEOUT`` -- fetching imagery from provider's system took too long. * ``NO-VALID-PROVIDER-DATA`` -- no valid imagery was available for the selected area in scene. This can happen only when requesting clipped imagery. * ``NO-THUMBNAIL-AVAILABLE`` -- no valid thumbnail was available for the selected scene. * ``NO-BASEMAP-AVAILABLE`` -- no valid basemap was available for selected path. Kraken API Error Codes ---------------------- * ``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 :ref:`api.kraken`. * ``SCENES-HAVE-NO-INTERSECTION`` -- footprints of provided scenes don't intersect. * ``VERSION-MISMATCH`` -- versions changed during analysis. Run the analysis again later. * ``UNSUPPORTED-FILE-NAME`` -- requested file is not supported. * ``INVALID-TILE-COORDINATES`` -- provided tile coordinates are not valid. * ``TILE-DOES-NOT-EXIST`` -- requested tile does not exist. * ``NOT-PERMITTED-COORDINATES`` -- user does not have permission to request scene with these coordinates as the tile is outside the region analyzed by the user. * ``INVALID-MAP-ID`` -- provided map ID is invalid. * ``SCENES-WITH-SAME-DATETIME`` -- Scenes provided for grouping have identical datetimes, which is forbidden. .. only:: not holygrail Credits API Error Codes ----------------------- - ``INVALID-GEOJSON`` -- requested GeoJSON doesn't fit requirements of the API. - ``NO-VALID-BINDING`` -- affected user is not bound to any company. See :ref:`api.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 :ref:`api.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. GeoJSON DB API Error Codes ------------------------------------------ * ``NON-EXISTENT-FEATURE`` -- GeoJSON feature does not exist. * ``MALFORMED-QUERY`` -- query cannot be parsed. .. only:: not holygrail Datacube API Error Codes ------------------------ - ``TOO-MANY-DATAPOINTS`` -- query matched too many data-points. You may - further limit amount of returned data by for example limiting data-range. - ``NO-MATCHING-PACKAGE`` -- none of permission packages assigned to calling - user matches request filters. - ``NON-EXISTENT-PACKAGE`` -- requested package does not exist. - ``NON-EXISTENT-PRODUCT`` -- requested product does not exist. - ``DUPLICATE-DATAPOINTS`` -- some of the supplied data-points are already in - Datacube API. You may remove these and re-run the request. - ``UNSUPPORTED-POSTPROCESS`` -- Your query contains unsupported postprocess - operation. - ``NON-EXISTENT-TABLE`` -- requested table does not exist. - ``PRODUCT-HAS-NO-DATA`` -- there are no data for given product. ***************** Asynchronous APIs ***************** .. Define the anchor after the header to prevent it being swallowed by only. .. _api.mechanics.asynchronous: 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 :ref:`Tasking API `. To get a finished pipeline result, request ``../retrieve``. .. _api.mechanics.asynchronous.initiate: .. http:post:: /.../initiate :>json string pipelineId: ID of the processing pipeline. It will be used later to check pipeline status and to retrieve pipeline result. :>json string status: status of the pipeline at the time the response was generated. See :ref:`Tasking API ` to learn more about pipeline statuses. :>json int nextTry: recommended delay in seconds before first status check. See :ref:`Tasking API ` :>json str subGeometryId: This is only provided in Kraken Release initiate endpoint if ``subGeometry`` was present in the request. See :ref:`Release with subGeometry `. **Example response**: .. sourcecode:: json { "nextTry": 5, "pipelineId": "3g4PovfhGxmymQolpgvv", "status": "NEW" } **Example with subGeometryId response**: .. sourcecode:: json { "nextTry": 5, "pipelineId": "3g4PovfhGxmymQolpgvv", "status": "NEW", "subGeometryId": "0123456789abcdef" } Pipeline is stopped and set to the ``FAILED`` status if an error occurred 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 :ref:`api.mechanics.errors`. .. _api.mechanics.asynchronous.retrieve: .. http:post:: /.../retrieve :` APIs may be paginated. In the case of asynchronous APIs a new pipeline is started for every new requested page.