> For the complete documentation index, see [llms.txt](https://docs.geosamples.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.geosamples.org/api/auth.md).

# Auth

## Obtain JWT pair with connection claim

> Issues a refresh and access token pair that include the given \`connection\` identifier in the payload. Authenticate via DRF token header or by posting an ORCID \`token\`. Requires upload permission. Any prior outstanding token for the same connection is blacklisted first.

```json
{"openapi":"3.0.3","info":{"title":"SESAR API","version":"1.0.0"},"security":[{"tokenAuth":[]},{"jwtAuth":[]},{}],"components":{"securitySchemes":{"tokenAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"Token-based authentication with required prefix \"Token\""},"jwtAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"JwtConnectionPairSuccess":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JwtConnectionPairSuccessData"}},"required":["data"]},"JwtConnectionPairSuccessData":{"type":"object","properties":{"refresh":{"type":"string","description":"JWT refresh token"},"access":{"type":"string","description":"JWT access token"}},"required":["access","refresh"]}}},"paths":{"/api/auth/token/{connection}/":{"post":{"operationId":"auth_token_create","description":"Issues a refresh and access token pair that include the given `connection` identifier in the payload. Authenticate via DRF token header or by posting an ORCID `token`. Requires upload permission. Any prior outstanding token for the same connection is blacklisted first.","summary":"Obtain JWT pair with connection claim","parameters":[{"in":"path","name":"connection","schema":{"type":"string"},"description":"Opaque connection identifier stored on the issued tokens.","required":true}],"tags":["auth"],"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtConnectionPairSuccess"}}},"description":""}}}}}}
```

## POST /api/auth/token/blacklist/

> Takes a token and blacklists it. Must be used with the\
> \`rest\_framework\_simplejwt.token\_blacklist\` app installed.

```json
{"openapi":"3.0.3","info":{"title":"SESAR API","version":"1.0.0"},"paths":{"/api/auth/token/blacklist/":{"post":{"operationId":"auth_token_blacklist_create","description":"Takes a token and blacklists it. Must be used with the\n`rest_framework_simplejwt.token_blacklist` app installed.","tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenBlacklist"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/TokenBlacklist"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/TokenBlacklist"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenBlacklist"}}},"description":""}}}}},"components":{"schemas":{"TokenBlacklist":{"type":"object","properties":{"refresh":{"type":"string","writeOnly":true}},"required":["refresh"]}}}}
```

## Revoke JWT tokens without connection claim

> Blacklists all outstanding refresh tokens for the authenticated user that do not include a \`connection\` claim. Returns how many tokens were newly revoked.

```json
{"openapi":"3.0.3","info":{"title":"SESAR API","version":"1.0.0"},"security":[{"tokenAuth":[]},{"jwtAuth":[]}],"components":{"securitySchemes":{"tokenAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"Token-based authentication with required prefix \"Token\""},"jwtAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"JwtRevokeAllSuccess":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JwtRevokeAllSuccessData"}},"required":["data"]},"JwtRevokeAllSuccessData":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable count of tokens revoked"}},"required":["message"]}}},"paths":{"/api/auth/token/blacklist-all/":{"delete":{"operationId":"auth_token_blacklist_all_destroy","description":"Blacklists all outstanding refresh tokens for the authenticated user that do not include a `connection` claim. Returns how many tokens were newly revoked.","summary":"Revoke JWT tokens without connection claim","tags":["auth"],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtRevokeAllSuccess"}}},"description":""}}}}}}
```

## Refresh JWT token pair

> Exchanges a refresh token for a new refresh and access token pair. The previous refresh token is blacklisted. If the submitted refresh token carries a \`connection\` claim, the new tokens retain it on the access token.

```json
{"openapi":"3.0.3","info":{"title":"SESAR API","version":"1.0.0"},"paths":{"/api/auth/token/refresh/":{"post":{"operationId":"auth_token_refresh_create","description":"Exchanges a refresh token for a new refresh and access token pair. The previous refresh token is blacklisted. If the submitted refresh token carries a `connection` claim, the new tokens retain it on the access token.","summary":"Refresh JWT token pair","tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRefresh"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/TokenRefresh"}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/TokenRefresh"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtRefreshPairSuccess"}}},"description":""}}}}},"components":{"schemas":{"TokenRefresh":{"type":"object","properties":{"access":{"type":"string","readOnly":true},"refresh":{"type":"string"}},"required":["access","refresh"]},"JwtRefreshPairSuccess":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JwtRefreshPairSuccessData"}},"required":["data"]},"JwtRefreshPairSuccessData":{"type":"object","properties":{"refresh":{"type":"string","description":"New JWT refresh token"},"access":{"type":"string","description":"New JWT access token"}},"required":["access","refresh"]}}}}
```

## Current user details

> Returns the authenticated SESAR user profile. When the request is authenticated with a JWT that carries a \`connection\` claim, \`jwt\_connection\` echoes that value in uppercase; otherwise it is null.

```json
{"openapi":"3.0.3","info":{"title":"SESAR API","version":"1.0.0"},"security":[{"tokenAuth":[]},{"jwtAuth":[]}],"components":{"securitySchemes":{"tokenAuth":{"type":"apiKey","in":"header","name":"Authorization","description":"Token-based authentication with required prefix \"Token\""},"jwtAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"AuthUserDetailsSuccess":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AuthUserDetailsSuccessData"}},"required":["data"]},"AuthUserDetailsSuccessData":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/SesarUser"},"jwt_connection":{"type":"string","nullable":true,"description":"JWT `connection` claim when present, else null."}},"required":["jwt_connection","user"]},"SesarUser":{"type":"object","properties":{"individual":{"allOf":[{"$ref":"#/components/schemas/Individual"}],"readOnly":true},"email":{"type":"string","nullable":true,"maxLength":255},"registration_date":{"type":"string","format":"date-time"},"orcid":{"type":"string","nullable":true,"maxLength":19},"doi_prefix":{"type":"string","maxLength":10},"upload_permission_status":{"type":"integer","maximum":2147483647,"minimum":-2147483648,"nullable":true},"notification_preferences":{},"is_staff":{"type":"boolean","readOnly":true},"is_admin":{"type":"integer","readOnly":true},"storage_used":{"type":"integer","maximum":9223372036854776000,"minimum":-9223372036854776000,"format":"int64"},"storage_limit":{"type":"integer","maximum":9223372036854776000,"minimum":-9223372036854776000,"format":"int64"}},"required":["individual","is_admin","is_staff","storage_limit","storage_used"]},"Individual":{"type":"object","properties":{"id":{"type":"integer","readOnly":true},"label":{"type":"string","nullable":true,"maxLength":200},"fname":{"type":"string","nullable":true,"maxLength":100},"lname":{"type":"string","nullable":true,"maxLength":100},"alt_label":{"type":"string","nullable":true,"maxLength":100},"description":{"type":"string","nullable":true},"address":{"type":"string","nullable":true,"maxLength":500},"email":{"type":"string","nullable":true,"maxLength":255},"phone":{"type":"string","nullable":true,"maxLength":255},"fax":{"type":"string","nullable":true,"maxLength":255},"individual_uri":{"type":"string","nullable":true,"maxLength":255},"institutions":{"type":"array","items":{"$ref":"#/components/schemas/Institution"},"readOnly":true},"institution_detail":{"type":"string","nullable":true,"maxLength":255},"country":{"type":"string","readOnly":true},"can_edit":{"type":"string","readOnly":true}},"required":["can_edit","country","id","institutions"]},"Institution":{"type":"object","properties":{"id":{"type":"integer","readOnly":true},"institution_type":{"type":"string","readOnly":true},"label":{"type":"string","maxLength":200},"alt_label":{"type":"string","nullable":true,"maxLength":200},"description":{"type":"string","nullable":true},"country":{"type":"string","readOnly":true},"country_subdivision":{"type":"string","nullable":true,"maxLength":255},"city":{"type":"string","nullable":true,"maxLength":255},"ror":{"type":"string","nullable":true,"maxLength":25},"parent_institutions":{"type":"string","readOnly":true},"can_edit":{"type":"string","readOnly":true},"created_by":{"type":"integer","nullable":true}},"required":["can_edit","country","id","institution_type","label","parent_institutions"]}}},"paths":{"/api/auth/user/":{"get":{"operationId":"auth_user_retrieve","description":"Returns the authenticated SESAR user profile. When the request is authenticated with a JWT that carries a `connection` claim, `jwt_connection` echoes that value in uppercase; otherwise it is null.","summary":"Current user details","tags":["auth"],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthUserDetailsSuccess"}}},"description":""}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.geosamples.org/api/auth.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
