{
  "openapi": "3.0.0",
  "info": {
    "contact": {
      "name": "EchoSync Integrations API",
      "email": "IntegrationsAPI@echo.com"
    },
    "version": "1.0.0",
    "title": "Authorizer API",
    "description": "The EchoSync Authorizer API is the authentication service for the EchoSync\nplatform. It validates your application credentials and issues OAuth 2.0\nBearer tokens that grant access to EchoSync APIs.\n\nNot every EchoSync API uses the Authorizer, and not every one requires a\nBearer token. The Carrier API requires a Bearer token from this service. The\nPricing API accepts either a Bearer token or Basic Authentication. The\nShipper API uses Basic Authentication only and does not use this service.\n\nWhere a Bearer token is required, send it in the `Authorization` header:\n```\nAuthorization: Bearer {your_token}\n```\n\n## Token Lifecycle\n\n> **Important**\n> **Reuse your token until it expires.** Do not request a new token on every API call. \n> Cache the token and use it for its full validity period. \n> Requesting new tokens repeatedly within the same validity window may trigger rate limiting.\n\n- Access tokens are valid for **86400 seconds** (24 hours) from the time they are issued.\n- The endpoint `/token` response includes:\n  - `expires_in` — token lifetime in **seconds** (used to determine when the token should be refreshed)\n  - `scope` — the permissions granted to the token, defining which APIs it can access\n- A `401 Unauthorized` response from any EchoSync API indicates the token is expired or invalid. \n  In this case, request a new token and retry the request.\n\n## Rate Limiting\n\nTo ensure fair usage, maintain service availability, and protect system performance, requests may be subject to rate limiting. \nWhen usage exceeds allowed thresholds, requests can be temporarily throttled or rejected until the limit window resets.\n"
  },
  "servers": [
    {
      "description": "Production",
      "url": "https://auth.echo.com"
    }
  ],
  "tags": [
    {
      "name": "token",
      "description": "Obtaining and using tokens"
    }
  ],
  "paths": {
    "/token": {
      "post": {
        "summary": "Obtain a bearer token from Echo Global Logistics",
        "tags": [
          "token"
        ],
        "description": "Exchanges your application credentials for an OAuth 2.0 Bearer token\nusing the Client Credentials flow.\n\nSubmit your `client_id`, `client_secret`, `grant_type`, and `scope`\nas form fields. On success, the response contains the `access_token`\nand its expiration time (`expires_in`, in seconds).\n\nCache and reuse the token for its full lifetime. Only call this\nendpoint again after the token expires.\n",
        "operationId": "token",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string",
                    "description": "The supplied client ID generated for your application"
                  },
                  "client_secret": {
                    "type": "string",
                    "description": "The supplied client secret generated for your application <p>**Required if grant_type is** ***client_credentials***</p>"
                  },
                  "grant_type": {
                    "type": "string",
                    "description": "The type of grant you are using to obtain a token",
                    "enum": [
                      "client_credentials"
                    ]
                  },
                  "scope": {
                    "type": "string",
                    "description": "The scope(s) being requested by the application <p>Scopes are space-delimited</p> <p>Scopes that are granted will be returned in the access token</p> <p>**Required if grant_type is** ***client_credentials***</p>",
                    "enum": [
                      "quotes:create",
                      "tender:action",
                      "load_status:read",
                      "invoice:read",
                      "connect_api:action",
                      "loads:read",
                      "loads:action"
                    ]
                  }
                },
                "required": [
                  "client_id",
                  "client_secret",
                  "grant_type",
                  "scope"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/TokenResponse"
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_client": {
                    "summary": "Invalid client id",
                    "value": {
                      "error": "invalid_request",
                      "error_desc": "Resource not found"
                    }
                  },
                  "invalid_grant": {
                    "summary": "Grant has been used or has expired",
                    "value": {
                      "error": "invalid_grant",
                      "error_desc": "grant request is invalid"
                    }
                  },
                  "missing_param": {
                    "summary": "Missing required parameter",
                    "value": {
                      "error": "invalid_request",
                      "error_desc": "missing required parameter(s). (redirect_uri)"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "failed_auth": {
                    "summary": "Failed authentication",
                    "value": {
                      "error": "invalid_request",
                      "error_desc": "Authentication Failed"
                    }
                  },
                  "no_access": {
                    "summary": "No access",
                    "value": {
                      "error": "invalid_request",
                      "error_desc": "Access is unauthorized"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Token": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string",
            "description": "JSON Web Token (JWT) that represents a session generated for a client"
          },
          "expires_in": {
            "type": "integer",
            "description": "Number of seconds until the session expires"
          },
          "token_type": {
            "type": "string",
            "description": "Type of access token - always set to Bearer"
          },
          "scope": {
            "type": "string",
            "description": "scope(s) approved with the token"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Short indicator of error type"
          },
          "error_desc": {
            "type": "string",
            "description": "Description of error"
          }
        }
      }
    },
    "responses": {
      "GenericSuccessResponse": {
        "description": "Success"
      },
      "TokenResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Token"
            },
            "examples": {
              "grant_type_client_credentials": {
                "summary": "Grant type as client_credentials",
                "value": {
                  "access_token": "NWE4Nzg2ZDEtNzQyMS00ZDViLThjMjctMGQwNjlmZjU5MWNkBGjFElT7CWzl0d....",
                  "expires_in": 3600,
                  "token_type": "Bearer",
                  "scope": "quotes:create"
                }
              }
            }
          }
        }
      },
      "UnauthorizedResponse": {
        "description": "Unauthorized",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "failed_auth": {
                "summary": "Failed authentication",
                "value": {
                  "error": "invalid_request",
                  "error_desc": "Authentication Failed"
                }
              },
              "no_access": {
                "summary": "No access",
                "value": {
                  "error": "invalid_request",
                  "error_desc": "Access is unauthorized"
                }
              }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "basicAuth": {
        "type": "http",
        "scheme": "basic"
      },
      "apiKey": {
        "type": "apiKey",
        "name": "x-api-key",
        "in": "header"
      }
    }
  }
}