Overview

The Magic package for Python is your entry-point to secure, passwordless authentication for your application. This guide will cover some important topics for getting started with Magic Python package and to make the most of Magic’s features.

Getting Started

The Magic class is the entry-point to the Magic SDK. It must be instantiated with a Magic secret key.

Installation

The Magic Admin Python SDK requires Python 3.11 or higher.
pip install magic-admin

Constructor

Magic()
ParameterTypeDefinition
api_secret_keystrYour secret API Key retrieved from the Magic Dashboard.
client_id?strYour Magic client ID. If not provided, will be fetched automatically.
retries?numTotal number of retries to allow. Default: 3.
timeout?numA period of time the request is going to wait for a response. Default: 10.
backoff_factor?numA backoff factor to apply between retry attempts. Default: 0.02.

Initialization

Initialize Magic instance.
Python
from magic_admin import Magic

magic = Magic(api_secret_key='<SECRET_API_KEY>')

Token Resource

The token resource and its methods are accessible on the Magic instance by the Token attribute. It provides methods to interact with the DID Token.
The token resource does not make any API calls to the Magic server.

get_issuer

Extracts the iss from the DID Token.
Python
Token.get_issuer(did_token)
Arguments
  • did_token (str): A DID Token generated by a Magic User on the client-side
Raises
  • DIDTokenMalformed if the given DID Token is malformed
Returns
  • A Decentralized ID (iss) of the Magic user who generated the DID Token

get_public_address

Gets the cryptographic public address of the Magic User who generated the supplied DID Token.
Python
Token.get_public_address(did_token)
Arguments
  • did_token (str): A DID Token generated by a Magic user on the client-side
Raises
  • DIDTokenMalformed if the given DID Token is malformed
Returns
  • A public address of the Magic User who generated the DID Token. Currently, this value is associated with the Ethereum blockchain.

decode

Decodes a DID Token from a Base64 string into a tuple of its individual components: proof and claim. This method allows you decode the DID Token and inspect the token. You can apply your own rules and validations on top of the current Token.validate method.
Python
Token.decode(did_token)
Arguments
  • did_token (str): A DID Token generated by a Magic user on the client-side
Raises
  • DIDTokenMalformed if the given DID Token is malformed
Returns
  • proof (str): A digital signature that proves the validity of the given claim
  • claim (dict): Unsigned data the user asserts. This should equal the proof after Elliptic Curve recovery. See Decentralized ID Token Specification for fields inside the claim.

validate

Validates a DID token.
Python
magic.Token.validate(did_token)
Arguments
  • did_token (str): A DID Token generated by a Magic user on the client-side
Raises
  • DIDTokenMalformed if the given DID Token is malformed
  • DIDTokenInvalid if the given DID Token is invalid
Returns
  • None.

User Resource

The user resource and its methods are accessible on the Magic instance by the User attribute. It provides methods to interact with the User.

get_metadata_by_issuer

Retrieves information about the user by the supplied iss from the DID Token. This method is useful if you store the iss with your user data, which is recommended.
Python
User.get_metadata_by_issuer(issuer)
Arguments
  • issuer (str): The user’s Decentralized ID, which can be parsed using Token.get_issuer
Raises
  • RateLimitingError: If you have sent too many requests within a given period of time
  • BadRequestError: If the supplied parameters are invalid
  • AuthenticationError: If your API secret key cannot be authenticated with Magic API server
  • ForbiddenError: If your API secret key is not authorized to access the resources
  • APIError: For any other API error
  • APIConnectionError: If your server cannot communicate with the Magic server. Normally this is a network communication error.
See Error Handling for more examples.
Returns
  • A MagicResponse: The data field contains all of the user meta information.
    • issuer (str): The user’s Decentralized ID
    • public_address (str): The authenticated user’s public address (a.k.a.: public key). Currently, this value is associated with the Ethereum blockchain.
    • email (str): The user’s email address
    • phone_number (str): The user’s phone number
    • oauth_provider (str): OAuth provider, if any
    • wallets (arr): Array of user’s wallet addresses

get_metadata_by_public_address

Retrieves information about the user by the supplied public_address. This method is useful if you store the public_address with your user data.
Python
User.get_metadata_by_public_address(public_address)
Arguments Raises
  • RateLimitingError: If you have sent too many requests within a given period of time.
  • BadRequestError: If the supplied parameters are invalid
  • AuthenticationError: If your API secret key cannot be authenticated with Magic API server
  • ForbiddenError: If your API secret key is not authorized to access the resources
  • APIError: For any other API error
  • APIConnectionError: If your server cannot communicate with the Magic server. Normally this is a network communication error.
See Error Handling for more examples.
Returns
  • A MagicResponse: The data field contains all of the user meta information.
    • issuer (str): The user’s Decentralized ID
    • public_address (str): The authenticated user’s public address (a.k.a.: public key). Currently, this value is associated with the Ethereum blockchain.
    • email (str): The user’s email address
    • phone_number (str): The user’s phone number
    • oauth_provider (str): OAuth provider, if any
    • wallets (arr): Array of user’s wallet addresses

get_metadata_by_token

Retrieves information about the user by the supplied DID Token.
Python
User.get_metadata_by_token(did_token)
Arguments
  • did_token (str): A DID Token generated by a Magic User on the client-side.
Raises
  • RateLimitingError: If you have sent too many requests within a given period of time
  • BadRequestError: If the supplied parameters are invalid
  • AuthenticationError: If your API secret key cannot be authenticated with Magic API server
  • ForbiddenError: If your API secret key is not authorized to access the resources
  • APIError: For any other API error
  • APIConnectionError: If your server cannot communicate with the Magic server. Normally this is a network communication error.
See Error Handling for more examples.
Returns
  • A MagicResponse: The data field contains all of the user meta information.
    • issuer (str): The user’s Decentralized ID
    • public_address (str): The authenticated user’s public address (a.k.a.: public key). Currently, this value is associated with the Ethereum blockchain.
    • email (str): The user’s email address
    • phone_number (str): The user’s phone number
    • oauth_provider (str): OAuth provider, if any
    • wallets (arr): Array of user’s wallet addresses

logout_by_issuer

Logs a user out of all Magic SDK sessions given the user’s Decentralized ID (iss). This method is useful if you store the iss with your user data, which is recommended.
Python
User.logout_by_issuer(issuer)
Arguments
  • issuer (str): The user’s Decentralized ID, which can be parsed using Token.get_issuer
Raises
  • RateLimitingError: If you have sent too many requests within a given period of time
  • BadRequestError: If the supplied parameters are invalid
  • AuthenticationError: If your API secret key cannot be authenticated with Magic API server
  • ForbiddenError: If your API secret key is not authorized to access the resources
  • APIError: For any other API error
  • APIConnectionError: If your server cannot communicate with the Magic server. Normally this is a network communication error.
See Error Handling for more examples.
Returns

logout_by_public_address

Logs a user out of all Magic SDK sessions given the user’s public address. This method is useful if you store the public_address.
Python
User.logout_by_public_address(public_address)
Arguments
  • public_address (str): The user’s Ethereum public address
Raises
  • RateLimitingError: If you have sent too many requests within a given period of time
  • BadRequestError: If the supplied parameters are invalid
  • AuthenticationError: If your API secret key cannot be authenticated with Magic API server
  • ForbiddenError: If your API secret key is not authorized to access the resources
  • APIError: For any other API error
  • APIConnectionError: If your server cannot communicate with the Magic server. Normally this is a network communication error.
See Error Handling for more examples.
Returns

logout_by_token

Logs a user out of all Magic SDK sessions given the DID Token.
Python
User.logout_by_token(did_token)
Arguments
  • did_token (str): A DID Token generated by a Magic user on the client-side
Raises
  • RateLimitingError: If you have sent too many requests within a given period of time
  • BadRequestError: If the supplied parameters are invalid
  • AuthenticationError: If your API secret key cannot be authenticated with Magic API server
  • ForbiddenError: If your API secret key is not authorized to access the resources
  • APIError: For any other API error
  • APIConnectionError: If your server cannot communicate with the Magic server. Normally this is a network communication error.
See Error Handling for more examples.
Returns

Utils Resource

The utils resource provides utility methods for common operations like parsing authorization headers and validating token ownership for NFT gating.

parse_authorization_header

Extracts a DID token from an HTTP Authorization header.
Python
Utils.parse_authorization_header(header)
Arguments
  • header (str): The Authorization header string in Bearer {token} format
Raises
  • ExpectedBearerStringError: If header is not in the expected format
Returns
  • str: The DID token extracted from the header
Example
Python
from magic_admin import Magic

magic = Magic(api_secret_key='<SECRET_API_KEY>')

# Extract token from Authorization header
auth_header = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ..."
did_token = magic.Utils.parse_authorization_header(auth_header)

validate_token_ownership

Validates that a user owns a specific NFT token for token gating functionality.
Python
Utils.validate_token_ownership(did_token, contract_address, contract_type, rpc_url, token_id=None)
Arguments
  • did_token (str): The DID token to validate
  • contract_address (str): The smart contract address of the NFT
  • contract_type (str): Either 'ERC721' or 'ERC1155'
  • rpc_url (str): The RPC endpoint URL for the blockchain
  • token_id (str, optional): Required for ERC1155 contracts
Raises
  • ValueError: If ERC1155 is specified without token_id
  • Exception: If DID token validation fails
Returns
  • dict: Response with validation result
    • valid (bool): Whether the user owns the token
    • error_code (str): Error code if validation fails
    • message (str): Human-readable error message
Example
Python
from magic_admin import Magic

magic = Magic(api_secret_key='<SECRET_API_KEY>')

# Validate ERC721 token ownership
result = magic.Utils.validate_token_ownership(
    did_token="eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ...",
    contract_address="0x1234567890123456789012345678901234567890",
    contract_type="ERC721",
    rpc_url="https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
)

if result['valid']:
    print("User owns the NFT!")
else:
    print(f"Validation failed: {result['message']}")

WalletType Enum

The WalletType enum provides support for multiple blockchain networks. Supported Networks
  • EVM Compatible: ETH, AVAX, CELO, HARMONY, ICON, ZILLIQA, HEDERA, CONFLUX, TERRA, TAQUITO, ED
  • Non-EVM: SOLANA, POLKADOT, NEAR, FLOW, TEZOS, COSMOS, ALGOD, BITCOIN, HELIUM

Multi-Chain User Metadata

The User resource supports retrieving metadata for specific wallet types across different blockchains.

get_metadata_by_issuer_and_wallet

Retrieves user metadata for a specific wallet type by issuer.
Python
User.get_metadata_by_issuer_and_wallet(issuer, wallet_type)
Arguments
  • issuer (str): The user’s Decentralized ID
  • wallet_type (WalletType): The specific wallet type to query
Returns
  • A MagicResponse: The data field contains user metadata for the specified wallet type

get_metadata_by_public_address_and_wallet

Retrieves user metadata for a specific wallet type by public address.
Python
User.get_metadata_by_public_address_and_wallet(public_address, wallet_type)
Arguments
  • public_address (str): The user’s public address
  • wallet_type (WalletType): The specific wallet type to query
Returns
  • A MagicResponse: The data field contains user metadata for the specified wallet type

get_metadata_by_token_and_wallet

Retrieves user metadata for a specific wallet type by DID token.
Python
User.get_metadata_by_token_and_wallet(did_token, wallet_type)
Arguments
  • did_token (str): A DID Token generated by a Magic user
  • wallet_type (WalletType): The specific wallet type to query
Returns
  • A MagicResponse: The data field contains user metadata for the specified wallet type
Example
Python
from magic_admin import Magic
from magic_admin.resources.wallet import WalletType

magic = Magic(api_secret_key='<SECRET_API_KEY>')

# Get user metadata for Solana wallet
response = magic.User.get_metadata_by_token_and_wallet(
    did_token="eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ...",
    wallet_type=WalletType.SOLANA
)

print(f"Solana wallet address: {response.data['public_address']}")

Response and Error Handling

Response

There is only one response object that will be returned from a successful API call.

MagicResponse

This is the interface to interact Magic API responses. It will only be returned if the API request status code is between 200 (inclusive) and 300 (exclusive). You will have access to the following attributes:
  • content (bytes): Raw content returned by the API response
  • status_code (num): HTTP status code for the given request
  • data (dict): Parsed content
Python
from magic_admin.response import MagicResponse

MagicResponse.content
MagicResponse.status
MagicResponse.data

Errors

The conventional HTTP response is adopted by the SDK. For the status code in:
  • 2XX - Indicates success
  • 4XX - Indicates client errors. Information provided to the SDK is invalid.
  • 5XX - Indicates server errors
Below is the error class inheritance which can help developers to programmatically handle the error cases.
MagicError
    |
    |------- RequestError
                  |
                  | ------- RateLimitingError
                  | ------- BadRequestError
                  | ------- AuthenticationError
                  | ------- ForbiddenError
                  | ------- APIError
                  | ------- APIConnectionError
   |
   | ------- DIDTokenInvalid
   |
   | ------- DIDTokenMalformed
   |
   | ------- DIDTokenExpired
   |
   | ------- ExpectedBearerStringError

MagicError

This is the base class of all the Magic SDK errors.
Python
MagicError(message=None)

RequestError

This is the base class of all the Magic API request errors. This error class will provide details of unsuccessful API requests.
Python
RequestError(
    message=None, http_status=None, http_code=None, http_resp_data=None,
    http_message=None, http_error_code=None, http_request_params=None,
    http_request_data=None, http_method=None,
)
CodeErrorDescription
429RateLimitingErrorToo many requests are submitted for a given period of time.
400BadRequestErrorThe API requests might have missing required fields or bad inputs.
401AuthenticationErrorThis means your API secret key is invalid.
403ForbiddenErrorThis normally means the given API secret key doesn’t have permission to perform the action on the given resources.
APIErrorThis is a generic API error that handles other status codes that are not explicitly handled. Ex: 500 , 404 , etc.
APIConnectionErrorNetwork connection error. This normally means the connection between between your application and Magic API server cannot be established.

DIDTokenInvalid

This means the given token fails the validation.

DIDTokenMalformed

This means the given token format is invalid.

DIDTokenExpired

This means the given token has expired.

ExpectedBearerStringError

This means the Authorization header is not in the expected Bearer {token} format.

Error Handling

It is recommended to implement error handling for API responses.
Python
from magic_admin import Magic
from magic_admin.error import (
    RateLimitingError, BadRequestError, AuthenticationError, 
    ForbiddenError, APIError, APIConnectionError,
    DIDTokenInvalid, DIDTokenMalformed, DIDTokenExpired,
    ExpectedBearerStringError
)

magic = Magic(api_secret_key='<SECRET_API_KEY>')

try:
    # Validate a DID token
    magic.Token.validate(did_token)
    print("Token is valid!")
    
    # Get user metadata
    user_data = magic.User.get_metadata_by_token(did_token)
    print(f"User email: {user_data.data['email']}")
    
except DIDTokenExpired:
    print("Token has expired, please login again")
except DIDTokenInvalid:
    print("Invalid token")
except DIDTokenMalformed:
    print("Malformed token")
except ExpectedBearerStringError:
    print("Invalid Authorization header format")
except RateLimitingError as e:
    print(f"Rate limit exceeded: {e}")
except AuthenticationError as e:
    print(f"Authentication failed: {e}")
except APIError as e:
    print(f"API error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")

Resources