> ## Documentation Index
> Fetch the complete documentation index at: https://finance.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Company Profile

> Retrieve comprehensive company information including business description, industry classification, headquarters location, and key identifiers. Essential for researching company background and fundamentals.

**Use Case:** Display company overview information on a stock detail page for investor research.


export default function OAuthLoginButton({scopes = "user:information account:information order:execution order:information position:information market:information calendar:information options:information analytics:information market:supplemental", responseType = "token", buttonText = "Authenticate with OAuth", showStatus = true}) {
  const [isDarkMode, setIsDarkMode] = useState(false);
  useEffect(() => {
    const checkDarkMode = () => {
      const isDark = document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || document.body.classList.contains("dark") || document.body.getAttribute("data-theme") === "dark";
      setIsDarkMode(isDark);
    };
    checkDarkMode();
    const htmlObserver = new MutationObserver(checkDarkMode);
    const bodyObserver = new MutationObserver(checkDarkMode);
    htmlObserver.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class", "data-theme", "style"]
    });
    bodyObserver.observe(document.body, {
      attributes: true,
      attributeFilter: ["class", "data-theme", "style"]
    });
    const interval = setInterval(checkDarkMode, 1000);
    return () => {
      htmlObserver.disconnect();
      bodyObserver.disconnect();
      clearInterval(interval);
    };
  }, []);
  const styles = useMemo(() => ({
    statusContainer: {
      marginBottom: "1.5rem",
      padding: "0.875rem 1rem",
      backgroundColor: isDarkMode ? "rgba(11, 170, 94, 0.08)" : "rgba(11, 170, 94, 0.06)",
      border: isDarkMode ? "1px solid rgba(11, 170, 94, 0.25)" : "1px solid rgba(11, 170, 94, 0.25)",
      borderRadius: "10px"
    },
    statusContent: {
      display: "flex",
      alignItems: "center",
      justifyContent: "space-between",
      gap: "1rem",
      flexWrap: "wrap"
    },
    statusLeft: {
      display: "flex",
      alignItems: "center",
      gap: "1rem",
      flexWrap: "wrap"
    },
    statusBadge: {
      display: "flex",
      alignItems: "center",
      gap: "0.5rem"
    },
    checkmark: {
      color: isDarkMode ? "#0BAA5E" : "#0BAA5E",
      fontSize: "1.25rem",
      fontWeight: "bold"
    },
    statusText: {
      color: isDarkMode ? "#0BAA5E" : "#0BAA5E",
      fontWeight: "600",
      fontSize: "0.95rem"
    },
    expiryText: {
      color: isDarkMode ? "#a1a1aa" : "#71717a",
      fontSize: "0.8125rem"
    },
    logoutButton: {
      padding: "0.375rem 0.75rem",
      backgroundColor: "transparent",
      color: isDarkMode ? "#e4e4e7" : "#3f3f46",
      border: isDarkMode ? "1px solid rgba(255, 255, 255, 0.1)" : "1px solid rgba(0, 0, 0, 0.1)",
      borderRadius: "6px",
      cursor: "pointer",
      fontSize: "0.8125rem",
      fontWeight: "500",
      transition: "background-color 0.15s ease"
    },
    logoutButtonHover: {
      backgroundColor: isDarkMode ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.04)"
    },
    buttonContainer: {
      marginBottom: "1.5rem",
      display: "flex",
      alignItems: "center",
      justifyContent: "space-between",
      gap: "1rem",
      padding: "0.875rem 1rem",
      backgroundColor: "transparent",
      border: isDarkMode ? "1px solid rgba(255, 255, 255, 0.1)" : "1px solid rgba(0, 0, 0, 0.08)",
      borderRadius: "10px"
    },
    loginButton: {
      display: "inline-flex",
      alignItems: "center",
      gap: "0.5rem",
      padding: "0.5rem 0.875rem",
      backgroundColor: "#0BAA5E",
      color: "white",
      border: "1px solid #0BAA5E",
      borderRadius: "8px",
      cursor: "pointer",
      fontSize: "0.8125rem",
      fontWeight: "500",
      lineHeight: "1.25rem",
      transition: "background-color 0.15s ease, border-color 0.15s ease",
      whiteSpace: "nowrap",
      flexShrink: 0
    },
    loginButtonHover: {
      backgroundColor: "#098F4E",
      borderColor: "#098F4E"
    },
    lockIcon: {
      width: "14px",
      height: "14px",
      flexShrink: 0
    },
    helpText: {
      margin: 0,
      fontSize: "0.8125rem",
      color: isDarkMode ? "#9ca3af" : "#6b7280",
      lineHeight: "1.5",
      flex: 1
    },
    modalDialog: {
      border: "none",
      backgroundColor: "transparent",
      padding: 0,
      margin: 0,
      maxWidth: "100%",
      maxHeight: "100%"
    },
    modalContent: {
      backgroundColor: isDarkMode ? "#0f0f10" : "#ffffff",
      border: isDarkMode ? "1px solid rgba(255, 255, 255, 0.08)" : "1px solid rgba(0, 0, 0, 0.08)",
      borderRadius: "12px",
      padding: "1.5rem",
      maxWidth: "500px",
      width: "100%",
      boxShadow: isDarkMode ? "0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.3)" : "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"
    },
    modalHeader: {
      display: "flex",
      justifyContent: "space-between",
      alignItems: "center",
      marginBottom: "1.5rem"
    },
    modalTitle: {
      margin: 0,
      fontSize: "1.125rem",
      fontWeight: "600",
      color: isDarkMode ? "#fafafa" : "#0a0a0a"
    },
    closeButton: {
      background: "none",
      border: "none",
      fontSize: "1.5rem",
      lineHeight: 1,
      color: isDarkMode ? "#a1a1aa" : "#71717a",
      cursor: "pointer",
      padding: "0",
      width: "2rem",
      height: "2rem",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      borderRadius: "6px",
      transition: "color 0.15s ease, background-color 0.15s ease"
    },
    form: {
      display: "flex",
      flexDirection: "column",
      gap: "1rem"
    },
    formGroup: {
      display: "flex",
      flexDirection: "column",
      gap: "0.5rem"
    },
    label: {
      fontSize: "0.8125rem",
      fontWeight: "500",
      color: isDarkMode ? "#e4e4e7" : "#3f3f46"
    },
    input: {
      padding: "0.5rem 0.75rem",
      border: isDarkMode ? "1px solid rgba(255, 255, 255, 0.1)" : "1px solid rgba(0, 0, 0, 0.1)",
      borderRadius: "8px",
      fontSize: "0.875rem",
      color: isDarkMode ? "#fafafa" : "#0a0a0a",
      backgroundColor: isDarkMode ? "rgba(255, 255, 255, 0.03)" : "#ffffff",
      transition: "border-color 0.15s ease, box-shadow 0.15s ease",
      outline: "none"
    },
    inputHelp: {
      margin: 0,
      fontSize: "0.75rem",
      color: isDarkMode ? "#a1a1aa" : "#71717a"
    },
    link: {
      color: "#0BAA5E",
      textDecoration: "none",
      fontWeight: "500"
    },
    errorBox: {
      padding: "0.75rem",
      backgroundColor: isDarkMode ? "rgba(220, 38, 38, 0.1)" : "rgba(220, 38, 38, 0.05)",
      border: isDarkMode ? "1px solid rgba(220, 38, 38, 0.3)" : "1px solid rgba(220, 38, 38, 0.2)",
      borderRadius: "8px",
      color: isDarkMode ? "#fca5a5" : "#dc2626",
      fontSize: "0.8125rem"
    },
    modalFooter: {
      display: "flex",
      gap: "0.5rem",
      justifyContent: "flex-end",
      marginTop: "0.5rem"
    },
    cancelButton: {
      padding: "0.5rem 0.875rem",
      backgroundColor: "transparent",
      color: isDarkMode ? "#e4e4e7" : "#3f3f46",
      border: isDarkMode ? "1px solid rgba(255, 255, 255, 0.1)" : "1px solid rgba(0, 0, 0, 0.1)",
      borderRadius: "8px",
      cursor: "pointer",
      fontSize: "0.8125rem",
      fontWeight: "500",
      lineHeight: "1.25rem",
      transition: "background-color 0.15s ease"
    },
    submitButton: {
      padding: "0.5rem 0.875rem",
      backgroundColor: "#0BAA5E",
      color: "white",
      border: "1px solid #0BAA5E",
      borderRadius: "8px",
      cursor: "pointer",
      fontSize: "0.8125rem",
      fontWeight: "500",
      lineHeight: "1.25rem",
      transition: "background-color 0.15s ease, border-color 0.15s ease"
    },
    submitButtonDisabled: {
      opacity: 0.6,
      cursor: "not-allowed"
    },
    redirectUrlContainer: {
      display: "flex",
      alignItems: "center",
      gap: "0.5rem",
      padding: "0.5rem 0.75rem",
      backgroundColor: isDarkMode ? "rgba(255, 255, 255, 0.03)" : "rgba(0, 0, 0, 0.03)",
      border: isDarkMode ? "1px solid rgba(255, 255, 255, 0.08)" : "1px solid rgba(0, 0, 0, 0.08)",
      borderRadius: "8px",
      fontSize: "0.8125rem",
      fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"
    },
    redirectUrlText: {
      flex: 1,
      color: isDarkMode ? "#a1a1aa" : "#71717a",
      overflow: "hidden",
      textOverflow: "ellipsis",
      whiteSpace: "nowrap"
    },
    copyButton: {
      padding: "0.25rem 0.625rem",
      backgroundColor: "transparent",
      color: isDarkMode ? "#e4e4e7" : "#3f3f46",
      border: isDarkMode ? "1px solid rgba(255, 255, 255, 0.1)" : "1px solid rgba(0, 0, 0, 0.1)",
      borderRadius: "6px",
      cursor: "pointer",
      fontSize: "0.75rem",
      fontWeight: "500",
      transition: "background-color 0.15s ease, border-color 0.15s ease",
      whiteSpace: "nowrap"
    },
    copyButtonHover: {
      backgroundColor: isDarkMode ? "rgba(255, 255, 255, 0.05)" : "rgba(0, 0, 0, 0.04)"
    },
    copyButtonCopied: {
      backgroundColor: "#0BAA5E",
      color: "white",
      border: "1px solid #0BAA5E"
    }
  }), [isDarkMode]);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [clientId, setClientId] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const [hasValidToken, setHasValidToken] = useState(false);
  const [tokenSource, setTokenSource] = useState(null);
  const [timeRemaining, setTimeRemaining] = useState(0);
  const [error, setError] = useState("");
  const [copied, setCopied] = useState(false);
  const redirectUrl = typeof window !== "undefined" ? window.location.origin + "/api-reference" : "";
  useEffect(() => {
    updateTokenState();
    if (window.AriesOAuth) {
      const lastClientId = window.AriesOAuth.getLastClientId();
      setClientId(lastClientId);
    }
    const handleTokenUpdate = () => {
      updateTokenState();
    };
    const handleOAuthError = event => {
      setError(event.detail.description || "Authentication failed");
      setIsLoading(false);
    };
    const handleOAuthSuccess = () => {
      setIsModalOpen(false);
      setIsLoading(false);
      setError("");
    };
    window.addEventListener("tokenStatusChanged", handleTokenUpdate);
    window.addEventListener("tokenUpdated", handleTokenUpdate);
    window.addEventListener("tokenCleared", handleTokenUpdate);
    window.addEventListener("oauthError", handleOAuthError);
    window.addEventListener("oauthSuccess", handleOAuthSuccess);
    const interval = setInterval(() => {
      if (hasValidToken) {
        updateTokenState();
      }
    }, 1000);
    return () => {
      window.removeEventListener("tokenStatusChanged", handleTokenUpdate);
      window.removeEventListener("tokenUpdated", handleTokenUpdate);
      window.removeEventListener("tokenCleared", handleTokenUpdate);
      window.removeEventListener("oauthError", handleOAuthError);
      window.removeEventListener("oauthSuccess", handleOAuthSuccess);
      clearInterval(interval);
    };
  }, [hasValidToken]);
  const updateTokenState = useCallback(() => {
    if (window.AriesOAuth) {
      const isValid = window.AriesOAuth.isAuthenticated();
      const remaining = window.AriesOAuth.getTimeRemaining();
      const knownExpiry = window.AriesOAuth.hasKnownExpiry ? window.AriesOAuth.hasKnownExpiry() : false;
      const source = window.AriesOAuth.getTokenSource ? window.AriesOAuth.getTokenSource() : null;
      setHasValidToken(isValid);
      setTokenSource(source);
      setTimeRemaining(knownExpiry && typeof remaining === "number" ? remaining : null);
    }
  }, []);
  const handleLogin = () => {
    setError("");
    setIsModalOpen(true);
  };
  const handleLogout = () => {
    if (window.AriesOAuth) {
      window.AriesOAuth.logout();
    }
    try {
      const cfg = window.AriesOAuth?.config;
      const tokenKey = cfg?.TOKEN_KEY ?? "aries_access_token";
      const expiryKey = cfg?.TOKEN_EXPIRY_KEY ?? "aries_token_timestamp";
      const sourceKey = cfg?.TOKEN_SOURCE_KEY ?? "aries_token_source";
      localStorage.removeItem(tokenKey);
      localStorage.removeItem(expiryKey);
      localStorage.removeItem(sourceKey);
    } catch (_) {}
    setHasValidToken(false);
    setTimeRemaining(null);
  };
  const handleOAuthRedirect = async e => {
    e.preventDefault();
    if (!clientId.trim()) {
      setError("Please enter your Client ID");
      return;
    }
    setIsLoading(true);
    try {
      if (window.AriesOAuth) {
        window.AriesOAuth.saveClientId(clientId.trim());
      }
      const returnPath = window.location.pathname + window.location.search + window.location.hash;
      sessionStorage.setItem("oauth_return_path", returnPath);
      const pkce = await window.AriesOAuth.generatePKCE();
      const authEndpoint = window.AriesOAuth?.config?.AUTH_ENDPOINT || "https://app.aries.com/oauth2/authorize";
      const authUrl = new URL(authEndpoint);
      authUrl.searchParams.set("client_id", clientId.trim());
      authUrl.searchParams.set("redirect_uri", redirectUrl);
      authUrl.searchParams.set("response_type", "code");
      authUrl.searchParams.set("code_challenge", pkce.challenge);
      authUrl.searchParams.set("code_challenge_method", "S256");
      authUrl.searchParams.set("scope", scopes);
      authUrl.searchParams.set("state", generateState());
      const fullAuthUrl = authUrl.toString();
      setTimeout(() => {
        window.location.href = fullAuthUrl;
      }, 100);
    } catch (error) {
      setError("Failed to initiate OAuth flow: " + error.message);
      setIsLoading(false);
    }
  };
  const generateState = () => {
    return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
  };
  const formatTimeRemaining = seconds => {
    const minutes = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${minutes}m ${secs}s`;
  };
  const copyRedirectUrl = () => {
    navigator.clipboard.writeText(redirectUrl).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }).catch(() => {});
  };
  const oauthDialogRef = useRef(null);
  const isLoadingRef = useRef(false);
  isLoadingRef.current = isLoading;
  const closeModal = useCallback(() => {
    if (!isLoading) {
      setIsModalOpen(false);
      setError("");
      setCopied(false);
    }
  }, [isLoading]);
  useEffect(() => {
    const el = oauthDialogRef.current;
    if (!el) return;
    if (isModalOpen) {
      if (!el.open) el.showModal();
    } else {
      if (el.open) el.close();
    }
  }, [isModalOpen]);
  useEffect(() => {
    const el = oauthDialogRef.current;
    if (!el) return;
    const onClose = () => {
      setIsModalOpen(false);
      setError("");
      setCopied(false);
    };
    const onCancel = e => {
      if (isLoadingRef.current) e.preventDefault();
    };
    el.addEventListener("close", onClose);
    el.addEventListener("cancel", onCancel);
    return () => {
      el.removeEventListener("close", onClose);
      el.removeEventListener("cancel", onCancel);
    };
  }, [hasValidToken, showStatus]);
  if (hasValidToken && showStatus && tokenSource === "oauth") {
    return <div style={styles.statusContainer}>
        <div style={styles.statusContent}>
          <div style={styles.statusLeft}>
            <div style={styles.statusBadge}>
              <span style={styles.checkmark}>✓</span>
              <span style={styles.statusText}>Authenticated</span>
            </div>
            {typeof timeRemaining === "number" ? <span style={styles.expiryText}>
                Expires in {formatTimeRemaining(timeRemaining)}
              </span> : null}
          </div>
          <button onClick={handleLogout} style={styles.logoutButton} onMouseEnter={e => e.target.style.backgroundColor = styles.logoutButtonHover.backgroundColor} onMouseLeave={e => e.target.style.backgroundColor = styles.logoutButton.backgroundColor}>
            Logout
          </button>
        </div>
      </div>;
  }
  const onDialogClick = e => {
    if (e.target === e.currentTarget) {
      closeModal();
    }
  };
  const modalMarkup = <dialog ref={oauthDialogRef} className="aries-oauth-dialog" data-oauth-theme={isDarkMode ? "dark" : "light"} style={styles.modalDialog} onClick={onDialogClick}>
      <div style={styles.modalContent} onClick={e => e.stopPropagation()}>
        <div style={styles.modalHeader}>
          <h3 style={styles.modalTitle}>OAuth Authentication</h3>
          <button type="button" onClick={closeModal} style={styles.closeButton} disabled={isLoading}>
            ×
          </button>
        </div>

        <form onSubmit={handleOAuthRedirect} style={styles.form}>
          <div style={styles.formGroup}>
            <label htmlFor="clientId" style={styles.label}>
              Client ID
            </label>
            <input id="clientId" type="text" value={clientId} onChange={e => setClientId(e.target.value)} placeholder="Enter your OAuth Client ID" style={styles.input} disabled={isLoading} />
            <p style={styles.inputHelp}>
              Get your Client ID from{" "}
              <a href="https://app.aries.com/client-center/api" target="_blank" rel="noopener noreferrer" style={styles.link}>
                Client Center / Manage Account → API
              </a>
            </p>
          </div>

          <div style={styles.formGroup}>
            <label style={styles.label}>Redirect URL</label>
            <div style={styles.redirectUrlContainer}>
              <span style={styles.redirectUrlText} title={redirectUrl}>
                {redirectUrl}
              </span>
              <button type="button" onClick={copyRedirectUrl} style={{
    ...styles.copyButton,
    ...copied ? styles.copyButtonCopied : {}
  }} onMouseEnter={e => {
    if (!copied) {
      e.currentTarget.style.backgroundColor = styles.copyButtonHover.backgroundColor;
    }
  }} onMouseLeave={e => {
    if (!copied) {
      e.currentTarget.style.backgroundColor = styles.copyButton.backgroundColor;
    }
  }}>
                {copied ? "✓ Copied" : "Copy"}
              </button>
            </div>
            <p style={styles.inputHelp}>
              Add this URL to your OAuth client's allowed redirect URIs
            </p>
          </div>

          {error && <div style={styles.errorBox}>{error}</div>}

          <div style={styles.modalFooter}>
            <button type="button" onClick={closeModal} style={styles.cancelButton} disabled={isLoading}>
              Cancel
            </button>
            <button type="submit" style={{
    ...styles.submitButton,
    ...isLoading ? styles.submitButtonDisabled : {}
  }} disabled={isLoading}>
              {isLoading ? "Redirecting..." : "Initiate Login"}
            </button>
          </div>
        </form>
      </div>
    </dialog>;
  return <>
      {}
      <div style={styles.buttonContainer}>
        <div style={styles.helpText}>
          <strong style={{
    color: isDarkMode ? "#e5e7eb" : "#374151"
  }}>
            Quick Auth:
          </strong>{" "}
          Authenticate once to auto-fill your Bearer token across all API
          endpoints
        </div>
        <button onClick={handleLogin} style={styles.loginButton} onMouseEnter={e => {
    e.currentTarget.style.backgroundColor = styles.loginButtonHover.backgroundColor;
    e.currentTarget.style.borderColor = styles.loginButtonHover.borderColor;
  }} onMouseLeave={e => {
    e.currentTarget.style.backgroundColor = styles.loginButton.backgroundColor;
    e.currentTarget.style.borderColor = styles.loginButton.borderColor;
  }}>
          <svg style={styles.lockIcon} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
            <path d="M7 11V7a5 5 0 0 1 10 0v4" />
          </svg>
          {buttonText}
        </button>
      </div>

      {modalMarkup}
    </>;
}

<Info>
  **Logo URL:** The `logo` field in the response is a proxied image URL. Use it as-is to display the company logo (e.g. in an `<img src="...">`). The URL has the form `https://api.aries.com/v1/logos/image/...` and does not expire; the API serves the image via its logo proxy.
</Info>

<OAuthLoginButton />


## OpenAPI

````yaml openapi.json GET /v1/company/profile
openapi: 3.0.3
info:
  contact:
    email: dev@aries.com
    name: Aries Financial
  description: >-
    OpenAPI Specification for the Aries trading platform API.


    # Authentication


    Learn how to authenticate with the Aries API using OAuth2 and manage access
    tokens in your SDK.


    ## Overview


    The Aries API uses **OAuth2 with Bearer tokens** (JWT format) for
    authentication. All API requests require a valid access token in the
    `Authorization` header:


    ```

    Authorization: Bearer <access_token>

    ```


    ## Providing Client ID and Client Secret (SDK)


    When using the generated SDK, provide your **Client ID** and **Client
    Secret** when you create the API client (e.g. in the constructor or security
    options). The SDK will use these to obtain and refresh the access token
    internally; you do not need to manage tokens yourself.


    Obtain your OAuth2 credentials from the Aries platform (e.g. Client Center /
    Manage Account at https://app.aries.com):


    - **Client ID** – Your application identifier (pass to SDK client)

    - **Client Secret** – Your application secret key (pass to SDK client; use
    PKCE for public clients where secret cannot be stored)


    ## Authentication Flow


    ### 1. Authorization Code Flow


    For server-side or confidential clients:


    1. **Redirect the user** to the authorization URL to sign in and consent:
     - **URL:** `https://app.aries.com/oauth2/authorize`
     - **Query params:** `response_type=code`, `client_id`, `redirect_uri`, `scope`, `state`

    2. **Exchange the code for tokens** (after user is redirected back with
    `?code=.`):
     - **POST** `https://api.aries.com/v1/oauth2/token`
     - **Body:** `grant_type=authorization_code`, `code`, `redirect_uri`, `client_id`, `client_secret`
     - Response includes `access_token` and `refresh_token`

    3. **Call the API** with the access token: `Authorization: Bearer
    <access_token>`


    ### 2. PKCE Flow


    For SPAs and mobile apps (public clients that cannot store `client_secret`):


    1. Generate a **code_verifier** (random string) and **code_challenge** =
    BASE64URL(SHA256(code_verifier)).

    2. **Redirect the user** to `https://app.aries.com/oauth2/authorize` with
    `code_challenge`, `code_challenge_method=S256`, plus `client_id`,
    `redirect_uri`, `scope`, `state`.

    3. **Exchange the code** at POST `https://api.aries.com/v1/oauth2/token`
    with `grant_type=authorization_code`, `code`, `redirect_uri`, `client_id`,
    `code_verifier` (no client_secret).

    4. Use the returned `access_token` as Bearer.


    ### 3. MFA Verification


    If the user has MFA enabled, the authorize step may return `is_mfa: true`
    and a `next_step_auth_id`. Call **POST**
    `https://api.aries.com/v1/oauth2/authorize/mfa` with `next_step_auth_id` and
    `verification_code` (6-digit code). Then continue with **POST**
    `/v1/oauth2/authorize/confirm` to get the authorization code, and exchange
    it at `/v1/oauth2/token`.


    ## Token Management


    - **Refresh when expired:** POST `https://api.aries.com/v1/oauth2/token`
    with `grant_type=refresh_token`, `client_id`, `client_secret`,
    `refresh_token`.

    - **Using a Bearer token directly:** If you already have an access token,
    set the header `Authorization: Bearer <access_token>` on every request. The
    SDK can accept a pre-obtained token and use it until it expires.


    ## OAuth2 Scopes


    Request only the scopes your application needs. Available scopes:


    | Scope | Description |

    |-------|-------------|

    | `user:information` | View user profile and personal details |

    | `account:information` | View account balances, positions, and transaction
    history |

    | `order:execution` | Place, modify, and cancel orders |

    | `order:information` | View order history and status |

    | `position:information` | View current positions and holdings |

    | `market:information` | Access live and historical market data |

    | `calendar:information` | Access earnings, economic, and market schedule
    data |

    | `options:information` | Access options chains and expiration data |

    | `analytics:information` | View analytics, ratings, and market insights |

    | `market:supplemental` | News, company profiles, financials, filings, ETF
    data, technical analysis |


    Specify multiple scopes as a space-separated string, e.g.
    `account:information order:execution market:information`.


    ## Security Best Practices


    - **Store credentials securely** – Use environment variables or a secrets
    manager for `client_id` and `client_secret`. Never hardcode them.

    - **Handle token expiration** – Check for 401 responses and refresh the
    token using the refresh_token, then retry the request.

    - **Use HTTPS** – All authorization and token endpoints must be called over
    HTTPS.

    - **Validate state** – When using the authorization code flow, validate the
    `state` parameter on the callback to prevent CSRF.


    ## Error Handling


    - **400 Bad Request** – Invalid or missing parameters, validation failures,
    or malformed JSON. Response bodies follow the same patterns as other errors
    (flat `error` string, optional `codes`, nested `error` object, or rarely no
    body).


    - **401 Unauthorized** – Invalid or expired access token; refresh the token
    or re-authenticate. JSON bodies are not identical on every route: you may
    see a flat `error` string (sometimes with `codes`), a nested `error` object
    (`type`, `code`, `message`), or rarely an empty body


    - **403 Forbidden** – Insufficient scope or permissions for the requested
    resource. Error JSON may be flat or nested, like 400/401.


    - **404 Not Found** – Resource does not exist or is not visible. Error JSON
    may be flat or nested.


    - **429 Too Many Requests** – Rate limit exceeded; slow down and respect
    `Retry-After` when the header is present. Error JSON may be flat or nested.


    - **500 / 5xx** – Server or upstream failure; retry with backoff. Do not
    depend on a single error JSON shape; some responses may have no body.



    ---


    Endpoints in this spec: health, OAuth2 (authorize, confirm, mfa, token),
    users, accounts, orders, market data, watchlist, chart, analytics,
    calendars, company, economy, financials, indices, options, news, and
    supplemental data.
  title: Aries API — OpenAPI Specification
  version: 1.0.0
servers:
  - description: Production server
    url: https://api.aries.com
security: []
tags:
  - description: >-
      Analytics endpoints for market data analysis including top gainers,
      losers, volume leaders, sector analysis, analyst ratings, market breadth,
      and net inflow
    name: Analytics
  - description: User management and profile endpoints
    name: Users
  - description: >-
      Order management endpoints for placing, updating, canceling, and
      previewing orders
    name: Orders
  - description: Account management endpoints for positions, orders, and balances
    name: Accounts
  - description: Calendar and mergers/acquisitions endpoints
    name: Calendar
  - description: >-
      Market data endpoints for symbol search, real-time data access, and equity
      details
    name: Market Data
  - description: >-
      Watchlist endpoints for listing, creating, updating, and deleting
      watchlists
    name: Watchlist
  - description: Chart endpoints for config, symbols, history, quotes, and server time
    name: Chart
  - description: News and news sentiment endpoints
    name: News
  - description: >-
      Indices endpoints for groups, list, search, bar, bars, chart-bars,
      realtime values
    name: Indices
  - description: Logos search and sync endpoints
    name: Logos
  - description: 'Corporate actions: spinoffs, tender offers, IPO calendar, dividends'
    name: Corporate Actions
  - description: 'Economy endpoints: inflation, inflation expectations, treasury yields'
    name: Economy
  - description: >-
      Options endpoints: expiry dates, contracts, activity, trades, quotes,
      unusual activity
    name: Options
  - description: >-
      Financials: reported, statements, revenue breakdown, short volume, ratios,
      short interest
    name: Financials
  - description: Signals and bull-bear cases
    name: Signals
  - name: Company
  - name: ETF
  - name: Filings
  - name: Market
  - name: Ownership
  - name: Stocks
  - name: Stock Estimates
  - name: Stock Alternative
    description: >-
      Transcripts, company presentation, social sentiment, investment themes,
      supply chain, and ESG data
  - name: Technical Analysis
paths:
  /v1/company/profile:
    get:
      tags:
        - Company
      summary: Get Company Profile
      description: >-
        Retrieve comprehensive company information including business
        description, industry classification, headquarters location, and key
        identifiers. At least one of symbol, ISIN, or CUSIP must be provided. If
        all three are omitted, the API returns 400 Bad Request. Response
        includes masked logo URL for privacy.
      operationId: get_v1_company_profile
      parameters:
        - name: symbol
          in: query
          description: >-
            Stock ticker symbol, such as AAPL. Optional if ISIN or CUSIP is
            provided. If symbol, isin, and cusip are all omitted, the API
            returns 400 Bad Request.
          required: false
          schema:
            example: AAPL
            type: string
        - name: isin
          in: query
          description: >-
            International Securities Identification Number. Optional if symbol
            or CUSIP is provided. If symbol, isin, and cusip are all omitted,
            the API returns 400 Bad Request.
          required: false
          schema:
            type: string
            example: US0378331005
        - name: cusip
          in: query
          description: >-
            Committee on Uniform Securities Identification Procedures code.
            Optional if symbol or ISIN is provided. If symbol, isin, and cusip
            are all omitted, the API returns 400 Bad Request.
          required: false
          schema:
            type: string
            example: '037833100'
      responses:
        '200':
          description: Company profile retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompanyProfile'
              examples:
                default:
                  value:
                    address: One Apple Park Way
                    alias: Apple Computer Inc, Apple Computer
                    city: Cupertino
                    country: US
                    currency: USD
                    cusip: '037833100'
                    description: >-
                      Apple Inc. designs, manufactures, and markets smartphones,
                      personal computers, tablets, wearables, and accessories
                      worldwide.
                    employeeTotal: 161000
                    estimateCurrency: USD
                    exchange: NASDAQ NMS - GLOBAL MARKET
                    sector: Technology
                    ggroup: Technology Hardware & Equipment
                    gind: Technology Hardware, Storage & Peripherals
                    gsector: Information Technology
                    gsubind: Technology Hardware, Storage & Peripherals
                    ipo: '1980-12-12'
                    irUrl: https://investor.apple.com/
                    isin: US0378331005
                    lei: HWUPKR0MPOU8FGXBT394
                    logo: https://api.aries.com/v1/logos/image/a/path
                    marketCapCurrency: USD
                    marketCapitalization: 4108269.25
                    naics: '334220'
                    naicsNationalIndustry: >-
                      Radio and Television Broadcasting and Wireless
                      Communications Equipment Manufacturing
                    naicsSector: Manufacturing
                    naicsSubsector: Computer and Electronic Product Manufacturing
                    name: Apple Inc
                    phone: '14089961010'
                    sedol: '2046251'
                    shareOutstanding: 14776.349609375
                    state: CA
                    ticker: AAPL
                    weburl: https://www.apple.com/
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - OAuth2:
            - market:supplemental
components:
  schemas:
    CompanyProfile:
      type: object
      description: >-
        Company profile data for research pages. Use it to explain what the
        company does, where it is listed, and how it is classified.
      properties:
        address:
          type: string
          description: >-
            Company headquarters street address. Use it for company profile and
            issuer detail pages.
        alias:
          type: string
          description: Comma-separated list of alternative names or aliases for the company
        city:
          type: string
          description: City where the company is headquartered
        country:
          type: string
          description: Country where the company is headquartered
        currency:
          type: string
          description: Currency used for financial reporting (e.g., USD, EUR)
        cusip:
          type: string
          description: >-
            CUSIP security identifier used in U.S. settlement and reference-data
            workflows.
        description:
          type: string
          description: Detailed business description
        employeeTotal:
          type: integer
          description: Total number of employees
        estimateCurrency:
          type: string
          description: Currency for earnings estimates
        exchange:
          $ref: '#/components/schemas/ExchangeCode'
        sector:
          type: string
          description: Industry sector classification
        ggroup:
          type: string
          description: GICS group classification
        gind:
          type: string
          description: GICS industry classification
        gsector:
          type: string
          description: GICS sector classification
        gsubind:
          type: string
          description: GICS sub-industry classification
        ipo:
          type: string
          description: Initial public offering date in YYYY-MM-DD format
        irUrl:
          type: string
          description: Investor relations website URL
        isin:
          type: string
          description: >-
            International Securities Identification Number. Use it for global
            security identification and reconciliation.
        lei:
          type: string
          description: >-
            Legal Entity Identifier for the company. Use it for institutional
            reference-data and compliance workflows.
        logo:
          type: string
          description: URL to the company's logo image (proxied through Aries API)
        marketCapCurrency:
          type: string
          description: Currency for market capitalization
        marketCapitalization:
          type: number
          description: Current market capitalization
        naics:
          type: string
          description: >-
            NAICS industry classification code. Use it for industry screening or
            peer grouping.
        naicsNationalIndustry:
          type: string
          description: NAICS national industry classification
        naicsSector:
          type: string
          description: NAICS sector classification
        naicsSubsector:
          type: string
          description: NAICS subsector classification
        name:
          type: string
          description: >-
            Official company name. Show this beside the ticker so users can
            confirm the company.
        phone:
          type: string
          description: Company's primary contact phone number
        sedol:
          type: string
          description: SEDOL security identifier used in global market reference data.
        shareOutstanding:
          type: number
          description: Total number of outstanding shares
        state:
          type: string
          description: State where the company is headquartered
        ticker:
          type: string
          description: >-
            Primary stock ticker symbol for the company. Use it to connect
            profile data to quotes, filings, and financials.
        weburl:
          type: string
          description: Company's official website URL
    ExchangeCode:
      type: string
      description: >-
        Two-to-three-letter exchange code identifying a global stock exchange
        (e.g. `US` = U.S. exchanges, `L` = London, `HK` = Hong Kong, `T` =
        Tokyo, `PA` = Paris). Used as the `exchange` query parameter for
        market-status and market-holiday endpoints. Other endpoints may return a
        different exchange-code format depending on the upstream data source.
      enum:
        - AD
        - AS
        - AT
        - AX
        - BA
        - BC
        - BD
        - BE
        - BH
        - BK
        - BO
        - BR
        - CA
        - CN
        - CO
        - CR
        - CS
        - DB
        - DE
        - DU
        - F
        - HA
        - HE
        - HK
        - HM
        - IC
        - IR
        - IS
        - JK
        - JO
        - KL
        - KQ
        - KS
        - KW
        - L
        - LS
        - MC
        - ME
        - MI
        - MT
        - MU
        - MX
        - NE
        - NL
        - NS
        - NZ
        - OL
        - OM
        - PA
        - PK
        - PM
        - PR
        - QA
        - RG
        - RO
        - SA
        - SC
        - SG
        - SI
        - SN
        - SR
        - SS
        - ST
        - SW
        - SX
        - SZ
        - T
        - TA
        - TG
        - TL
        - TO
        - TW
        - TWO
        - US
        - V
        - VI
        - VN
        - VS
        - WA
      default: US
      example: US
    AuthenticationErrorEnvelope:
      type: object
      description: >-
        JSON envelope where `error` is a nested object (`type`, `code`,
        `message`, …). Many services use this shape for 400, 401, 403, 404, 429,
        and 5xx when using the shared HTTP error format.
      properties:
        error:
          $ref: '#/components/schemas/AuthenticationErrorDetail'
        meta:
          type: object
          additionalProperties: true
          description: Optional metadata
    ErrorResponse:
      properties:
        codes:
          description: Structured error codes for programmatic handling
          items:
            $ref: '#/components/schemas/ErrorCode'
          type: array
        error:
          type: string
          description: >-
            Error detail as a string. Exact message content is not fixed and
            should not be hard-coded.
          example: string
        metadata:
          additionalProperties: true
          description: Additional error context
          type: object
      type: object
    AuthenticationErrorDetail:
      type: object
      description: >-
        Structured payload for the nested `error` object. Services using the
        shared Go error writer emit uppercase `type` values aligned with error
        categories (for example `VALIDATION`, `BAD_REQUEST`, `AUTHENTICATION`,
        `AUTHORIZATION`, `NOT_FOUND`, `RATE_LIMIT`, `INTERNAL`).
      properties:
        type:
          type: string
          description: >-
            Error category emitted by the shared error writer, such as
            VALIDATION, BAD_REQUEST, AUTHENTICATION, AUTHORIZATION, NOT_FOUND,
            RATE_LIMIT, or INTERNAL.
          example: AUTHENTICATION
        code:
          type: string
          description: Machine-readable code
          example: INVALID_TOKEN
        message:
          type: string
          description: >-
            Error detail as a string. Exact message content is not fixed and
            should not be hard-coded.
          example: string
        details:
          type: object
          additionalProperties: true
          description: Optional extra context
        request_id:
          type: string
          description: Request correlation id when provided
    ErrorCode:
      properties:
        code:
          description: Machine-readable error code
          example: INVALID_PASSWORD
          type: string
        description:
          description: Human-readable description of the error
          example: Password must be between 8 and 64 characters
          type: string
        field:
          description: Field name that caused the error
          example: password
          type: string
      type: object
  responses:
    BadRequest:
      description: >-
        Invalid query/path/body, malformed JSON, or failed validation.


        **Backend (shared HTTP errors):** Routes that use the shared error
        writer typically return a **nested** JSON object: `error.type` is an
        uppercase category such as `VALIDATION` or `BAD_REQUEST` (see the API
        implementation). Other routes may return the **flat** `ErrorResponse`
        shape (`error` as a string, optional `codes`). The body may rarely be
        empty.


        **OpenAPI:** Every operation’s **400** response references this
        component so the documented schema and examples stay aligned.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/AuthenticationErrorEnvelope'
              - $ref: '#/components/schemas/ErrorResponse'
            description: >-
              400 responses commonly use a nested `error` object (`type`,
              `code`, `message`, optional `details`). Some services still return
              flat `ErrorResponse` (`error` string, optional `codes`).
          examples:
            nested_shared_http_error:
              summary: Nested error (typical for shared WriteHTTPError-style responses)
              value:
                error:
                  type: VALIDATION
                  code: VALIDATION_ERROR
                  message: Query parameter validation failed
                  details:
                    fieldName: field is required
            nested_bad_request:
              summary: Nested error (BAD_REQUEST / invalid JSON)
              value:
                error:
                  type: BAD_REQUEST
                  code: INVALID_JSON
                  message: string
            flat_string:
              summary: Flat error string
              value:
                error: string
            flat_with_codes:
              summary: Flat error with field codes (some services)
              value:
                error: string
                codes:
                  - field: string
                    code: string
                    description: string
    Unauthorized:
      description: >-
        Authentication failed: missing credentials, invalid JWT, or expired
        access token.


        **Response body variants:** Some routes return JSON with a string
        `error` field (and optionally `codes` / `metadata`). Others return JSON
        where `error` is a structured object (`type`, `code`, `message`, and
        optionally `details`, `request_id`). In edge cases (for example certain
        gateway or middleware paths) the response may have **no body** even
        though the status is 401—clients should treat 401 as unauthenticated and
        refresh or re-authenticate regardless of body shape.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - $ref: '#/components/schemas/AuthenticationErrorEnvelope'
            description: >-
              401 responses may use a flat `ErrorResponse` shape or a nested
              `error` object. Inspect `error`: if it is a string, use the flat
              shape; if it is an object, use the structured shape.
          examples:
            flat_message:
              summary: Flat error string (typical)
              value:
                error: string
            flat_with_codes:
              summary: Flat error with structured codes
              value:
                error: string
                codes:
                  - code: string
                    description: string
            nested_error_object:
              summary: Nested error (shared HTTP error format)
              value:
                error:
                  type: AUTHENTICATION
                  code: INVALID_TOKEN
                  message: string
    Forbidden:
      description: >-
        Authenticated but not allowed to perform this action or access this
        resource (insufficient scope or role).


        **Response body variants:** Flat `ErrorResponse` or nested `error`
        object, same pattern as 400/401.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - $ref: '#/components/schemas/AuthenticationErrorEnvelope'
            description: 403 responses may use a flat or nested error shape.
          examples:
            flat:
              summary: Flat message
              value:
                error: string
            nested:
              summary: Nested error (shared HTTP error format)
              value:
                error:
                  type: AUTHORIZATION
                  code: INSUFFICIENT_SCOPE
                  message: string
    NotFound:
      description: >-
        The requested resource does not exist or is not visible to this caller.


        **Response body variants:** Flat `ErrorResponse` or nested `error`
        object.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - $ref: '#/components/schemas/AuthenticationErrorEnvelope'
            description: 404 responses may use a flat or nested error shape.
          examples:
            flat:
              summary: Flat message
              value:
                error: string
            nested:
              summary: Nested error (shared HTTP error format)
              value:
                error:
                  type: NOT_FOUND
                  code: RESOURCE_NOT_FOUND
                  message: string
    InternalServerError:
      description: >-
        Unexpected server error or upstream failure. **Retry with exponential
        backoff**; do not assume a specific JSON body shape.


        **Response body variants:** Flat `ErrorResponse`, nested `error` object,
        or occasionally a minimal message. Some paths may return **no body**.
      content:
        application/json:
          examples:
            flat_string:
              summary: Flat error string
              value:
                error: string
            nested_error_object:
              summary: Nested error (shared HTTP error format)
              value:
                error:
                  type: INTERNAL
                  code: INTERNAL_ERROR
                  message: string
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - $ref: '#/components/schemas/AuthenticationErrorEnvelope'
            description: 5xx responses may use a flat or nested error shape.
  securitySchemes:
    OAuth2:
      type: oauth2
      description: >-
        OAuth2 Bearer token: obtain an access token from the token endpoint and
        send it in the Authorization header.
      flows:
        clientCredentials:
          tokenUrl: https://api.aries.com/v1/oauth2/token
          refreshUrl: https://api.aries.com/v1/oauth2/token
          scopes:
            user:information: View user profile and personal details
            account:information: View account balances, positions, and transaction history
            order:execution: Place, modify, and cancel orders
            order:information: View order history and status
            position:information: View current positions and holdings
            market:information: Access live and historical market data
            calendar:information: Access earnings, economic, and market schedule data
            options:information: Access options chains and expiration data
            analytics:information: View analytics, ratings, and market insights
            market:supplemental: >-
              News, company profiles, financials, filings, ETF data, technical
              analysis
            user:management: >-
              Manage user-scoped resources such as watchlists and other saved
              configuration.
        authorizationCode:
          authorizationUrl: https://app.aries.com/oauth2/authorize
          tokenUrl: https://api.aries.com/v1/oauth2/token
          refreshUrl: https://api.aries.com/v1/oauth2/token
          scopes:
            user:information: View user profile and personal details
            account:information: View account balances, positions, and transaction history
            order:execution: Place, modify, and cancel orders
            order:information: View order history and status
            position:information: View current positions and holdings
            market:information: Access live and historical market data
            calendar:information: Access earnings, economic, and market schedule data
            options:information: Access options chains and expiration data
            analytics:information: View analytics, ratings, and market insights
            market:supplemental: >-
              News, company profiles, financials, filings, ETF data, technical
              analysis
            user:management: >-
              Manage user-scoped resources such as watchlists and other saved
              configuration.

````