Steem - Your Starting Point

Quick Start

You can start using the library with just a few lines of code, as seen in this quick example:

# first, we initialize Steem class
from steem import Steem
s = Steem()
# check @ned's balance
>>> s.get_account('ned')['sbd_balance']
'980.211 SBD'

# lets send $1.0 SBD to @ned
>>> s.commit.transfer(to='ned', amount=1, asset='SBD', account='furion')
{'expiration': '2017-03-12T17:54:43',
 'extensions': [],
 'operations': [['transfer',
   {'amount': '1.000 SBD', 'from': 'furion', 'memo': '', 'to': 'ned'}]],
 'ref_block_num': 23008,
 'ref_block_prefix': 961695589,
 'signatures': ['1f1322be9ca0c22b27c0385c929c9863901ac78cdaedea2162024ea040e22c4f8b542c02d96cbc761cbe4a188a932bc715bb7bcaf823b6739a44bb29fa85f96d2f']}

# yup, its there
>>> s.get_account('ned')['sbd_balance']
'981.211 SBD'

Importing your Steem Account

steem-python comes with a BIP38 encrypted wallet, which holds your private keys.

Alternatively, you can also pass required WIF’s to Steem() initializer.

from steem import Steem
s = Steem(keys=['<private_posting_key>', '<private_active_key>'])

Using the encrypted wallet is however a recommended way.

Please check steempy CLI to learn how to set up the wallet.

Interfacing with steemd

Steem() inherits API methods from Steemd, which can be called like so:

s = Steem()

s.get_content('author', 'permlink')
# and many more

You can see the list of available methods by calling help(Steem). If a method is not available trough the Python API, we can call it manually using s.exec():

s = Steem()

# this call
s.get_followers('furion', 'abit', 'blog', 10)

# is same as
       'furion', 'abit', 'blog', 10,

Commit and Wallet

Steem() comes equipped with Commit and Wallet, accessible via dot-notation.

s = Steem()

# accessing Commit methods

# accessing Wallet methods

Please check Transactions and Accounts documentation to learn more.


As displayed in the Quick Start above, Steem is the main class of this library. It acts as a gateway to other components, such as Steemd, Commit, Wallet and HttpClient.

Any arguments passed to Steem as kwargs will naturally flow to sub-components. For example, if we initialize Steem with steem = Steem(no_broadcast=True), the Commit instance is configured to not broadcast any transactions. This is very useful for testing.

class steem.steem.Steem(nodes=None, no_broadcast=False, **kwargs)

Connect to the Steem network.

  • nodes (list) – A list of Steem HTTP RPC nodes to connect to. If not provided, official Steemit nodes will be used.
  • debug (bool) – Elevate logging level to logging.DEBUG. Defaults to logging.INFO.
  • no_broadcast (bool) – If set to True, committal actions like sending funds will have no effect (simulation only).

Optional Arguments (kwargs):

  • keys (list) – A list of wif keys. If provided, the Wallet will use these keys rather than the ones found in BIP38 encrypted wallet.
  • unsigned (bool) – (Defaults to False) Use this for offline signing.
  • expiration (int) – (Defualts to 60) Size of window in seconds that the transaction needs to be broadcasted in, before it expires.

Steemd class instance. It can be used to execute commands against steem node.


If you would like to override the official Steemit nodes (default), you can pass your own. When currently used node goes offline, Steemd will automatically fail-over to the next available node.

nodes = [

s = Steemd(nodes)

Steemd API

Steemd contains API generating utilities. Steemd’s methods will be automatically available to Steem() classes. See Steem - Your Starting Point.

class steem.steemd.Steemd(nodes=None, **kwargs)

Connect to the Steem network.

Parameters:nodes (list) – A list of Steem HTTP RPC nodes to connect to. If not provided, official Steemit nodes will be used.
Returns:Steemd class instance. It can be used to execute commands against steem node.


If you would like to override the official Steemit nodes (default), you can pass your own. When currently used node goes offline, Steemd will automatically fail-over to the next available node.

nodes = [

s = Steemd(nodes)
broadcast_block(block: steem.block.Block)
broadcast_transaction(signed_transaction: steembase.transactions.SignedTransaction)
broadcast_transaction_synchronous(signed_transaction: steembase.transactions.SignedTransaction)

Identify the connected network. This call returns a dictionary with keys chain_id, prefix, and other chain specific settings

get_account(account: str)

Lookup account information such as user profile, public keys, balances, etc.

Parameters:account (str) – STEEM username that we are looking up.
Returns:Account information.
Return type:dict
get_account_bandwidth(account: str, bandwidth_type: object)

How many accounts are currently registered on STEEM?

get_account_history(account: str, index_from: int, limit: int)

History of all operations for a given account.

  • account (str) – STEEM username that we are looking up.
  • index_from (int) – The highest database index we take as a starting point.
  • limit (int) – How many items are we interested in.

List of operations.

Return type:



To get the latest (newest) operations from a given user furion, we should set the index_from to -1. This is the same as saying give me the highest index there is.

s.get_account_history('furion', index_from=-1, limit=3)

This will yield 3 recent operations like so:

  {'block': 9941972,
   'op': ['vote',
    {'author': 'breezin',
     'permlink': 'raising-children-is-not-childsplay-pro-s-and-con-s-of-being-a-young-parent',
     'voter': 'furion',
     'weight': 900}],
   'op_in_trx': 0,
   'timestamp': '2017-03-06T17:09:48',
   'trx_id': '87f9176faccc7096b5ffb5d12bfdb41b3c0b2955',
   'trx_in_block': 5,
   'virtual_op': 0}],
  {'block': 9942005,
   'op': ['curation_reward',
    {'comment_author': 'leongkhan',
     'comment_permlink': 'steem-investor-report-5-march-2017',
     'curator': 'furion',
     'reward': '112.397602 VESTS'}],
   'op_in_trx': 1,
   'timestamp': '2017-03-06T17:11:30',
   'trx_id': '0000000000000000000000000000000000000000',
   'trx_in_block': 5,
   'virtual_op': 0}],
  {'block': 9942006,
   'op': ['vote',
    {'author': 'ejhaasteem',
     'permlink': 'life-of-fishermen-in-aceh',
     'voter': 'furion',
     'weight': 100}],
   'op_in_trx': 0,
   'timestamp': '2017-03-06T17:11:30',
   'trx_id': '955018ac8efe298bd90b45a4fbd15b9df7e00be4',
   'trx_in_block': 7,
   'virtual_op': 0}]]

If we want to query for a particular range of indexes, we need to consider both index_from and limit fields. Remember, index_from works backwards, so if we set it to 100, we will get items 100, 99, 98, 97….

For example, if we’d like to get the first 100 operations the user did, we would write:

s.get_account_history('furion', index_from=100, limit=100)

We can get the next 100 items by running:

s.get_account_history('furion', index_from=200, limit=100)
get_account_references(account_id: int)
get_account_reputations(account: str, limit: int)
get_account_votes(account: str)

All votes the given account ever made.

Returned votes are in the following format:

{'authorperm': 'alwaysfelicia/time-line-of-best-times-to-post-on-steemit-mystery-explained',
'percent': 100,
'rshares': 709227399,
'time': '2016-08-07T16:06:24',
'weight': '3241351576115042'},
Parameters:account (str) – STEEM username that we are looking up.
Returns:List of votes.
Return type:list
get_accounts(account_names: list)

Lookup account information such as user profile, public keys, balances, etc.

This method is same as get_account, but supports querying for multiple accounts at the time.

get_active_votes(author: str, permlink: str)

Get all votes for the given post.

  • author (str) – OP’s STEEM username.
  • permlink (str) – Post identifier following the username. It looks like slug-ified title.

List of votes.

Return type:



s.get_active_votes('mynameisbrian', 'steemifying-idioms-there-s-no-use-crying-over-spilt-milk')


[{'percent': 10000,
  'reputation': '36418980678',
  'rshares': 356981288,
  'time': '2017-03-06T20:04:18',
  'voter': 'dailystuff',
  'weight': '2287202760855'},
 {'percent': 10000,
  'reputation': 3386400109,
  'rshares': 364252169,
  'time': '2017-03-06T19:32:45',
  'voter': 'flourish',
  'weight': '2334690471157'}]

Get a list of currently active witnesses.


Fetch the full list of STEEM usernames.

get_api_by_name(api_name: str)
get_block(block_num: int)

Get the full block, transactions and all, given a block number.

Parameters:block_num (int) – Block number.
Returns:Block in a JSON compatible format.
Return type:dict


{'extensions': [],
 'previous': '0087a2372163ff5c5838b09589ce281d5a564f66',
 'timestamp': '2017-01-29T02:47:33',
 'transaction_merkle_root': '4ddc419e531cccee6da660057d606d11aab9f3a5',
 'transactions': [{'expiration': '2017-01-29T02:47:42',
   'extensions': [],
   'operations': [['comment',
     {'author': 'hilarski',
      'body': '',
      'json_metadata': '{"tags":["motocross"],"image":[""],"app":"steemit/0.1"}',
      'parent_author': 'b0y2k',
      'parent_permlink': 'ama-supercross-round-4-phoenix-2017',
      'permlink': 're-b0y2k-ama-supercross-round-4-phoenix-2017-20170129t024725575z',
      'title': ''}]],
   'ref_block_num': 41495,
   'ref_block_prefix': 2639073901,
   'signatures': ['2058b69f4c15f704a67a7b5a7996a9c9bbfd39c639f9db19b99ecad8328c4ce3610643f8d1b6424c352df120614cd535cd8f2772fce68814eeea50049684c37d69']}],
 'witness': '',
 'witness_signature': '1f115745e3f6fee95124164f4b57196c0eda2a700064faa97d0e037d3554ee2d5b618e6bfd457473783e8b8333724ba0bf93f0a4a7026e7925c8c4d2ba724152d4'}
get_block_header(block_num: int)

Get block headers, given a block number.

Parameters:block_num (int) – Block number.
Returns:Block headers in a JSON compatible format.
Return type:dict


{'extensions': [],
 'previous': '0087a2372163ff5c5838b09589ce281d5a564f66',
 'timestamp': '2017-01-29T02:47:33',
 'transaction_merkle_root': '4ddc419e531cccee6da660057d606d11aab9f3a5',
 'witness': ''}
get_blocks(block_nums: typing.List[int])

Fetch multiple blocks from steemd at once, given a range.

Parameters:block_nums (list) – A list of all block numbers we would like to tech.
Returns:An ensured and ordered list of all get_block results.
Return type:dict
get_blocks_range(start: int, end: int)

Fetch multiple blocks from steemd at once, given a range.

  • start (int) – The number of the block to start with
  • end (int) – The number of the block at the end of the range. Not included in results.

An ensured and ordered list of all get_block results.

Return type:


get_blog(account: str, entry_id: int, limit: int)
get_blog_authors(blog_account: str)
get_blog_entries(account: str, entry_id: int, limit: int)

Get witness elected chain properties.

{'account_creation_fee': '30.000 STEEM',
 'maximum_block_size': 65536,
 'sbd_interest_rate': 250}
get_comment_discussions_by_payout(discussion_query: dict)

Get internal chain configuration.

get_content(author: str, permlink: str)
get_content_replies(author: str, permlink: str)
get_conversion_requests(account: str)

Get the average STEEM/SBD price.

This price is based on moving average of witness reported price feeds.

{'base': '0.093 SBD', 'quote': '1.010 STEEM'}
get_discussions_by_active(discussion_query: dict)
get_discussions_by_author_before_date(author: str, start_permlink: str, before_date: steembase.types.PointInTime, limit: int)
get_discussions_by_blog(discussion_query: dict)
get_discussions_by_cashout(discussion_query: dict)
get_discussions_by_children(discussion_query: dict)
get_discussions_by_comments(discussion_query: dict)
get_discussions_by_created(discussion_query: dict)
get_discussions_by_feed(discussion_query: dict)
get_discussions_by_hot(discussion_query: dict)
get_discussions_by_payout(discussion_query: dict)
get_discussions_by_promoted(discussion_query: dict)
get_discussions_by_votes(discussion_query: dict)
get_escrow(from_account: str, escrow_id: int)
get_expiring_vesting_delegations(account: str, start: steembase.types.PointInTime, limit: int)
get_feed(account: str, entry_id: int, limit: int)
get_feed_entries(account: str, entry_id: int, limit: int)

Get the hourly averages of witness reported STEEM/SBD prices.

{'current_median_history': {'base': '0.093 SBD', 'quote': '1.010 STEEM'},
 'id': 0,
 'price_history': [{'base': '0.092 SBD', 'quote': '1.010 STEEM'},
  {'base': '0.093 SBD', 'quote': '1.020 STEEM'},
  {'base': '0.093 SBD', 'quote': '1.010 STEEM'},
  {'base': '0.094 SBD', 'quote': '1.020 STEEM'},
  {'base': '0.093 SBD', 'quote': '1.010 STEEM'},
get_follow_count(account: str)
get_followers(account: str, start_follower: str, follow_type: str, limit: int)
get_following(account: str, start_follower: str, follow_type: str, limit: int)

Get the current version of the chain.


This is not the same as latest minor version.

get_key_references(public_keys: typing.List[str])
get_liquidity_queue(start_account: str, limit: int)

Get the liquidity queue.


This feature is currently not in use, and might be deprecated in the future.

get_market_history(bucket_seconds: int, start: steembase.types.PointInTime, end: steembase.types.PointInTime)

Returns the market history for the internal SBD:STEEM market.


Returns the bucket seconds being tracked by the plugin.

get_open_orders(account: str)
get_ops_in_block(block_num: int, virtual_only: bool)
get_order_book(limit: int)

Get the internal market order book.

This method will return both bids and asks.

Parameters:limit (int) – How many levels deep into the book to show.
Returns:Order book.
Return type:dict




{'asks': [{'created': '2017-03-06T21:29:54',
   'order_price': {'base': '513.571 STEEM', 'quote': '50.000 SBD'},
   'real_price': '0.09735752213423265',
   'sbd': 50000,
   'steem': 513571},
  {'created': '2017-03-06T21:01:39',
   'order_price': {'base': '63.288 STEEM', 'quote': '6.204 SBD'},
   'real_price': '0.09802806219188472',
   'sbd': 6204,
   'steem': 63288}],
 'bids': [{'created': '2017-03-06T21:29:51',
   'order_price': {'base': '50.000 SBD', 'quote': '516.503 STEEM'},
   'real_price': '0.09680485882947436',
   'sbd': 50000,
   'steem': 516503},
  {'created': '2017-03-06T17:30:24',
   'order_price': {'base': '36.385 SBD', 'quote': '379.608 STEEM'},
   'real_price': '0.09584887568228277',
   'sbd': 36385,
   'steem': 379608}]}
get_owner_history(account: str)
get_post_discussions_by_payout(discussion_query: dict)
get_posts(limit=10, sort='hot', category=None, start=None)

Get multiple posts in an array.

  • limit (int) – Limit the list of posts by limit
  • sort (str) – Sort the list by “recent” or “payout”
  • category (str) – Only show posts in this category
  • start (str) – Show posts after this post. Takes an identifier of the form @author/permlink
get_potential_signatures(signed_transaction: steembase.transactions.SignedTransaction)

Get promoted posts

get_reblogged_by(author: str, permlink: str)
get_recent_trades(limit: int) → typing.List[typing.Any]

Returns the N most recent trades for the internal SBD:STEEM market.

get_recovery_request(account: str)
get_replies(author, skip_own=True)

Get replies for an author

  • author (str) – Show replies for this author
  • skip_own (bool) – Do not show my own replies
get_replies_by_last_update(account: str, start_permlink: str, limit: int)
get_required_signatures(signed_transaction: steembase.transactions.SignedTransaction, available_keys: list)
get_reward_fund(fund_name: str = 'post')

Get details for a reward fund.

Right now the only pool available is ‘post’.


{'content_constant': '2000000000000',
 'id': 0,
 'last_update': '2017-04-09T19:18:57',
 'name': 'post',
 'percent_content_rewards': 10000,
 'percent_curation_rewards': 2500,
 'recent_claims': '10971122501158586840771928156084',
 'reward_balance': '555660.895 STEEM'}
get_savings_withdraw_from(account: str)
get_savings_withdraw_to(account: str)
get_state(path: str)
get_tags_used_by_author(account: str)

Returns the market ticker for the internal SBD:STEEM market.

get_trade_history(start: steembase.types.PointInTime, end: steembase.types.PointInTime, limit: int)

Returns the trade history for the internal SBD:STEEM market.

get_transaction(transaction_id: str)
get_transaction_hex(signed_transaction: steembase.transactions.SignedTransaction)

Get steemd version of the node currently connected to.

get_vesting_delegations(account: str, from_account: str, limit: int)

Returns the market volume for the past 24 hours.

get_withdraw_routes(account: str, withdraw_route_type: str)
get_witness_by_account(account: str)
get_witnesses(witness_ids: list)
get_witnesses_by_vote(from_account: str, limit: int)

Newest block number.


Newest irreversible block number.

login(username: str, password: str)
lookup_account_names(account_names: list)
lookup_accounts(after: typing.Union[str, int], limit: int) → typing.List[str]

Get a list of usernames from all registered accounts.

  • after (str, int) – Username to start with. If ‘’, 0 or -1, it will start at beginning.
  • limit (int) – How many results to return.

List of usernames in requested chunk.

Return type:


lookup_witness_accounts(from_account: str, limit: int)
set_max_block_age(max_block_age: int)
stream_comments(*args, **kwargs)

Generator that yields posts when they come in

To be used in a for loop that returns an instance of Post().

verify_account_authority(account: str, keys: list)
verify_authority(signed_transaction: steembase.transactions.SignedTransaction)

Setting Custom Nodes

There are 3 ways in which you can set custom steemd nodes to use with steem-python.

1. Global, permanent override: You can use steempy set nodes command to set one or more node URLs. The nodes need to be separated with comma (,) and shall contain no whitespaces.

~ % steempy config
| Key                 | Value  |
| default_vote_weight | 100    |
| default_account     | furion |
~ % steempy set nodes
~ % steempy config
| Key                 | Value                         |
| default_account     | furion                        |
| default_vote_weight | 100                           |
| nodes               | |
~ % steempy set nodes,
~ % steempy config
| Key                 | Value                                                    |
| nodes               |, |
| default_vote_weight | 100                                                      |
| default_account     | furion                                                   |
~ %

To reset this config run steempy set nodes ''.

2. For Current Python Process: You can override default Steemd instance for current Python process, by overriding the instance singleton. You should execute the following code when your program starts, and from there on out, all classes (Blockchain, Account, Post, etc) will use this as their default instance.

from steem.steemd import Steemd
from steem.instance import set_shared_steemd_instance

steemd_nodes = [

3. For Specific Class Instance: Every class that depends on steemd comes with a steemd_instance argument. You can override said steemd instance, for any class you’re initializing (and its children).

This is useful when you want to contain a modified steemd instance to an explicit piece of code (ie. for testing).

from steem.steemd import Steemd
from steem.account import Account
from steem.Blockchain import Blockchain

steemd_nodes = [
custom_instance = Steemd(nodes=steemd_nodes)

account = Account('furion', steemd_instance=custom_instance)
blockchain = Blockchain('head', steemd_instance=custom_instance)