refactored API. haven't tested yet