FMS Open Platform Third-Party Integration | FieldFusion Developer Center

FMS Open Platform

Third-Party Integration Notice

This page is for third-party integrators and summarizes credential preparation, OAuth2 token exchange, open API calling rules, request signing, error codes, and integration recommendations.

Overview

First receive credentials, then finish OAuth2 authorization and token exchange, and finally call open APIs with signed requests.

When a third-party system connects to FMS Open Platform, it must first receive client credentials and signing credentials from the platform. The authorization flow is used to obtain an access token. Business APIs are called through /openapi/** and must include the token, API Key, timestamp, nonce, and signature in the request headers.

1. Receive credentials

Get clientId, clientSecret, apiKey, apiSecret, and the registered callback URL.

2. Exchange for token

Use the one-time authorization code with /oauth2/token to obtain an access_token.

3. Call open APIs

Sign the path, query string, and request body, then call /openapi/** with the required headers.

Preparation

Before integration, the platform should provide client credentials, signing credentials, and the registered redirect URI.

Before integration, the platform should provide the following credentials:

  • clientId
  • clientSecret
  • apiKey
  • apiSecret
  • Registered redirectUri
Credential Purpose Notes
clientId + clientSecret Use /oauth2/token to obtain or refresh a token. clientSecret is sensitive. The platform does not expose an interface to retrieve the current plain-text secret.
apiKey + apiSecret Generate request signatures when calling /openapi/**. apiSecret is sensitive and should never appear in front-end pages, logs, or public configuration.
redirectUri Receives callback parameters after authorization completes. It must be registered in advance and must match exactly during token exchange.
Security note: If clientSecret is lost, contact a platform administrator to rotate it. Do not share full secrets or tokens through logs, screenshots, or ticket bodies.

OAuth2 Authorization and Token Exchange

After authorization, the callback returns code, state, and domain, which are then used to exchange for an access token.

Authorization result

After a user completes authorization, the third-party callback address receives code, state, and domain.

  • code: one-time authorization code.
  • state: pass-through state value originally sent by the third party.
  • domain: used to choose the target service domain for subsequent open platform requests.

Exchange authorization code for token

POST /oauth2/token
Content-Type: application/json

{
  "grantType": "authorization_code",
  "code": "authorization-code",
  "redirectUri": "https://third.example.com/callback",
  "clientId": "your-client-id",
  "clientSecret": "your-client-secret"
}

Successful response example:

{
  "code": 0,
  "message": "Success",
  "data": {
    "access_token": "access-token",
    "token_type": "Bearer",
    "scope": "default"
  },
  "requestId": "req-1234567890abcd",
  "timestamp": 1760000000000
}
  • Request fields use camelCase, such as grantType.
  • Token fields in the response use snake_case, such as access_token.
  • An authorization code can be consumed only once.
  • Missing, expired, or already consumed authorization codes currently map to 10004.
  • Tokens do not use a fixed absolute expiration strategy. As long as valid requests continue, the platform renews them automatically.

Refresh token

{
  "grantType": "refresh_token",
  "refreshToken": "old-access-token",
  "clientId": "your-client-id",
  "clientSecret": "your-client-secret"
}

Pass the previous access token through the refreshToken field.

Open API Calling Rules

All open business APIs use /openapi/** and require the shared authentication headers plus the request signature.

All open business APIs use the /openapi/** prefix, for example /openapi/customer/page, /openapi/farm/page, and /openapi/task/page.

Required headers

Authorization: Bearer <access_token>
X-Api-Key: <apiKey>
X-Timestamp: <unix timestamp in milliseconds>
X-Nonce: <unique value per request>
X-Signature-Version: v1
X-Signature: <signature result>
Content-Type: application/json

HTTP status codes

Status Meaning
200 OK The request was processed successfully. Continue interpreting the business result through the response body code.
400 Bad Request Parameters are invalid or missing, or the request format does not match expectations.
401 Unauthorized Authentication failed, such as a missing Authorization header, an invalid token, a missing signature, or signature validation failure.
403 Forbidden The server received the request, but the current client is disabled or a downstream business validation failed.
404 Not Found The requested path does not exist.
429 Too Many Requests Rate limiting was triggered.

For /openapi/**, signature-related failures currently return HTTP 401. Some 10001 responses may include a more specific message, but program logic should rely on code.

Unified response structure

{
  "code": 0,
  "message": "Success",
  "data": {},
  "requestId": "req-xxxx",
  "timestamp": 1760000000000
}
{
  "code": 10014,
  "message": "Request signature is invalid",
  "data": null,
  "requestId": "req-xxxx",
  "timestamp": 1760000000000
}

Log the request path, request time, HTTP status, requestId, and response code on the caller side.

Signature Rules

The signature uses HmacSHA256 plus Base64, based on method, path, canonical query string, body hash, and shared header values.

Algorithm

  • Algorithm: HmacSHA256
  • Output: Base64
  • Version: v1
  • Key: the assigned apiSecret

Signature validation proves that the request was sent by an integrator holding the correct apiSecret and that the request was not modified in transit.

String to sign

HTTP_METHOD + "\n" +
REQUEST_PATH + "\n" +
CANONICAL_QUERY_STRING + "\n" +
BODY_SHA256 + "\n" +
X-Api-Key + "\n" +
X-Timestamp + "\n" +
X-Nonce
  • HTTP_METHOD must be uppercase, such as GET or POST.
  • REQUEST_PATH must be the full request path without domain, protocol, or QueryString.
  • CANONICAL_QUERY_STRING is the sorted and encoded query string without the leading ?.
  • Query parameters must be sorted by parameter name, then by parameter value when names are equal.
  • Both query keys and values should be UTF-8 encoded and then URL-encoded. In Java, URLEncoder is recommended, and + should be replaced with %20.
  • If no query parameters exist, the blank line must still be preserved.
  • BODY_SHA256 is the SHA-256 of the raw request body bytes in lowercase hexadecimal.
  • X-Api-Key, X-Timestamp, and X-Nonce must match the actual request header values exactly.

The SHA-256 for an empty request body is always:

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Canonical Query String example

/openapi/task/page?pageNum=1&pageSize=20&name=demo%20task

The CANONICAL_QUERY_STRING that participates in signing is:

name=demo%20task&pageNum=1&pageSize=20

Do not include the leading ? or the full URL in the string to sign.

Body hash rule

The hashed content must be the exact JSON byte sequence that is ultimately sent. Re-serializing after signing can change field order or whitespace and break signature validation.

{"name":"demo","pageNum":1,"pageSize":20}

Signing flow

  1. Prepare the request method, path, query parameters, and raw request body.
  2. Compute CANONICAL_QUERY_STRING.
  3. Compute BODY_SHA256.
  4. Build the string to sign in the fixed field order, using \n between lines.
  5. Use apiSecret to apply HmacSHA256 to the string to sign.
  6. Base64-encode the result and place it in the X-Signature header.

Common signature failures

  • 10013 SIGNATURE_REQUIRED: usually means X-Signature or X-Signature-Version is missing.
  • 10014 SIGNATURE_INVALID: first check whether the request path included the domain, whether query parameters were sorted, and whether the body was re-serialized after signing.
  • 10015 SIGNATURE_TIMESTAMP_EXPIRED: check whether the client machine time differs too much from standard time.
  • 10016 SIGNATURE_NONCE_REPLAY: the same X-Nonce was reused.
  • If headers look correct but validation still fails, verify that the correct apiSecret is being used for the right environment. Test and production credentials must not be mixed.

Anti-Replay Requirements

The timestamp must stay inside the allowed window, and a nonce can be used only once within that window.

  • X-Timestamp must fall inside the allowed time window.
  • X-Nonce can be used only once inside the valid window.
  • Reusing a nonce returns 10016.

Current Open API List

The currently exposed interfaces are organized into master data, business operations, and prescription or sampling groups.

Master data APIs

  • POST /openapi/customer/page
  • POST /openapi/farm/page
  • POST /openapi/farmland/page
  • POST /openapi/boundary/page
  • POST /openapi/baseline/page
  • POST /openapi/employee/page

Business and operation APIs

  • POST /openapi/task/page
  • POST /openapi/agriPlan/page
  • POST /openapi/graderTask/page
  • POST /openapi/grader/page
  • POST /openapi/machine/page
  • POST /openapi/machineTools/page
  • POST /openapi/marker/page
  • POST /openapi/kitAutoSteering/page

Prescription and sampling APIs

  • POST /openapi/imagePrescription/page
  • POST /openapi/simplePrescription/page
  • POST /openapi/soilPrescription/page
  • POST /openapi/yieldPrescription/page
  • POST /openapi/sampleGroup/page
  • POST /openapi/sampleGroup/samplePoints/list

Common Error Codes

The main error groups cover token and authorization, signature and security, parameter validation, rate limiting or idempotency, and system failures.

Category Codes Description
Token and authorization 10001 INVALID_TOKEN
10004 INVALID_AUTHORIZATION_CODE
20001 CLIENT_NOT_FOUND
20002 CLIENT_DISABLED
20003 CLIENT_SECRET_MISMATCH
30001 REDIRECT_URI_MISMATCH
30002 REDIRECT_URI_NOT_ALLOWED
Missing, expired, or already consumed authorization codes currently map to 10004.
Signature and security 10010 API_KEY_INVALID
10011 API_KEY_DISABLED
10012 API_KEY_EXPIRED
10013 SIGNATURE_REQUIRED
10014 SIGNATURE_INVALID
10015 SIGNATURE_TIMESTAMP_EXPIRED
10016 SIGNATURE_NONCE_REPLAY
10010 is protocol-reserved. In the current implementation, an unknown apiKey may appear as 20001 CLIENT_NOT_FOUND.
Parameter and business validation 20004 ACCESS_VALIDATION_FAILED
40001 INVALID_PARAM
40002 PARAM_REQUIRED
40003 PARAM_OUT_OF_RANGE
40004 PARAM_FORMAT_ERROR
20004 means the request passed open platform authentication but failed downstream FMS validation.
Rate limit and idempotency 50001 RATE_LIMIT_EXCEEDED
50002 IDEMPOTENCY_KEY_REQUIRED
50003 IDEMPOTENCY_KEY_CONFLICT
50002 and 50003 are returned only when idempotency checks are enabled and the endpoint requires Idempotency-Key.
System errors 90001 INTERNAL_ERROR
90004 REMOTE_CALL_ERROR
System exceptions usually collapse into 90001 or 90004. Third-party callers typically do not receive 90002 or 90003 directly in the current version.

Integration Recommendations

During integration, wrap a shared client, record requestId, and finish test-environment verification before asking for production credentials.

  • Wrap a shared HTTP client on the caller side to centralize signing and common headers.
  • Record the requestId from every response to make joint debugging and issue tracing easier.
  • Do not reuse X-Nonce.
  • During integration, let your program logic prioritize the response body code; message is better suited to log analysis.
  • Third parties should complete test-environment verification before requesting production endpoints and related details. The platform can reject production credential issuance if test-environment integration has not been completed.
  • Do not print full apiSecret, full access_token, or full authorization codes in logs.
This page is organized from the third-party integration notice and is intended as an implementation guide. API fields, error codes, and signing rules should follow the current implementation and formal release notes.